java - 如何防止数据库关闭后线程继续运行?

标签 java android multithreading sqlite android-database

public class ValuatorService extends Service {
    SQLLiteAdapter db;
    Context context;
    String strLat, strLong, strTempLat, strTempLong;
    static String prospect_no;
    public Database database;
    long boolDistanceDetail;
    static double dist, roundOff;
    SQLLiteAdapter adapter;
    public ArrayList<String> latDetails;
    private ArrayList<Double> distanceList;
    static int loop = 0;

    public ValuatorService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        db = new SQLLiteAdapter(this);
        db.open();
        context = getApplicationContext();
        database = Database.getDBAdapterInstance(context);
        distanceList = new ArrayList<>();
    }

    @SuppressLint("NewApi")
    @Override
    public void onStart(Intent intent, int startId) {
        // Perform your long running operations here.

        long boolDistanceDetail = db.insertDistanceDetail(Util
                .getstringvaluefromkey(MenuScreen.activity, "LoginName"), Util
                .getstringvaluefromkey(MenuScreen.activity, "trackid"), Util
                .getstringvaluefromkey(MenuScreen.activity, "SimNo"), Util
                .getstringvaluefromkey(MenuScreen.activity, "req_no"), Util
                .getstringvaluefromkey(MenuScreen.activity, "customer_name"),
                Util.getstringvaluefromkey(MenuScreen.activity, "cus_mobile"),
                Util.getstringvaluefromkey(MenuScreen.activity, "city"), Util
                        .getstringvaluefromkey(MenuScreen.activity,
                                "prospect_no"));
        Log.e("Tab1 Insert", String.valueOf(boolDistanceDetail));
        prospect_no = Util.getstringvaluefromkey(MenuScreen.activity,
                "prospect_no");

        loop = 0;
        getLatLong();

    }

    @Override
    public void onDestroy() {

        db.sumDistance();
        db.close();
    }

    public void getLatLong() {
        loop++;
        LocationResult locationResult = new MyLocation.LocationResult() {
            @Override
            public void gotLocation(Location location) {
                try {
                    strLat = String.valueOf(location.getLatitude());
                    strLong = String.valueOf(location.getLongitude());
                    if (loop == 1) {
                        boolDistanceDetail = db.insertLatLong(prospect_no,
                                strLat, strLong, "0");
                        strTempLat = strLat;
                        strTempLong = strLong;
                    } else if (loop > 1) {
                        boolDistanceDetail = db.insertLatLong(
                                prospect_no,
                                strLat,
                                strLong,
                                String.valueOf(distFrom(
                                        Float.parseFloat(strTempLat),
                                        Float.parseFloat(strTempLong),
                                        Float.parseFloat(strLat),
                                        Float.parseFloat(strLong))));
                        strTempLat = strLat;
                        strTempLong = strLong;
                        Log.e("distFrom",
                                String.valueOf(distFrom(
                                        Float.parseFloat(strTempLat),
                                        Float.parseFloat(strTempLong),
                                        Float.parseFloat(strLat),
                                        Float.parseFloat(strLong))));

                    }

                    Log.e("Tab1 Insert", String.valueOf(boolDistanceDetail));
                    Log.e("OldLat - OldLong", strTempLat + " - " + strTempLong);
                    Log.e("Lat - Long", strLat + " - " + strLong);

                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            getLatLong();
                            distanceList.add(roundOff);
                            Log.d("ValuatorService", "" + distanceList);
                        }
                    }, 10000);
                } catch (Exception ex) {
                    Log.e("Error", ex.toString());
                }
            }
        };

        MyLocation myLocation = new MyLocation();
        myLocation.getLocation(context, locationResult);
    }

    private static float distFrom(float fltFromLat, float fltFromLong,
            float fltToLat, float fltToLong) {
        double earthRadius = 6371000; // meters
        double dLat = Math.toRadians(fltToLat - fltFromLat);
        double dLng = Math.toRadians(fltToLong - fltFromLong);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(fltFromLat))
                * Math.cos(Math.toRadians(fltToLat)) * Math.sin(dLng / 2)
                * Math.sin(dLng / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        dist = (float) ((earthRadius * c) / 1000);
        roundOff = Math.round(dist * 100.0) / 100.0;

        return (float) roundOff;
    }
}

停止服务后,我在 log cat 中收到错误:

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.mahindra.tev/databases/TravelDistance.db

最佳答案

这意味着您正在从数据库异步读取/写入,一旦调用 onDestroy() ,就无法访​​问它,因为您关闭了它。

一个简单的解决方案是不在 onDestroy() 方法中调用 db.close() ,而仅在您实际完成时才调用。

另一个解决方案是在实际插入/更新行之前检查是否db.isOpen()

关于java - 如何防止数据库关闭后线程继续运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32733548/

相关文章:

java - 如何编译两次?

java - base64解码后的文件不等于原始未编码文件

Java 泛型通配符 : Why does this not compile?

android - 更改不同选项卡的操作栏颜色

java - 当用户点击离开EditText时如何触发事件?

java - 如何创建签名为 List 的方法

android - PANIC : Broken AVD system path. 检查您的 ANDROID_SDK_ROOT 值

c++ - 使用 vector 中的每 2 个元素进行计算的嵌套循环中的段错误

java - 多线程ArrayList迭代

javascript - 异步 JavaScript 解决方法