2

Android システムは、開いている SQLite データベースを自動的に閉じますか? データにアクセスするためのシングルトン クラスを実装しましたが、ワーカー スレッドでメソッドを実行する必要がある場合があります。バックグラウンドで実行されるクエリとの同期機能があります。コードは次のとおりです。

public ArrayList<ActualCall> getUnsentCalls(boolean forUnsentSignature) {
    ArrayList<ActualCall> calls = new ArrayList<ActualCall>();

    Cursor c;
    open();

    if (forUnsentSignature)
        c = db.rawQuery("SELECT * FROM " + TXN_ACTUAL_CALL_COMPONENT
                + " WHERE sentFlag=1 and sigSentFlag=?", new String[] {"0"});
    else
        c = db.rawQuery("SELECT * FROM " + TXN_ACTUAL_CALL_COMPONENT
                + " WHERE sentFlag=? AND signature != ''", new String[] {"0"});

    if (c.moveToFirst()) {
        do {
            if (!db.isOpen())
                open();
            ActualCall call = new ActualCall();

            call.setAcpComponentId(c.getString(c.getColumnIndex("acpComponentId")));
            call.setAcpDate(c.getString(c.getColumnIndex("acpDate")));
            call.setAcpId(c.getString(c.getColumnIndex("acpId")));
            call.setCallEndTime(c.getString(c.getColumnIndex("callEndTime")));
            call.setCallStartTime(c.getString(c.getColumnIndex("callStartTime")));
            call.setCoordinates(c.getString(c.getColumnIndex("coordinates")));
            call.setDeviceTimestamp(c.getString(c.getColumnIndex("deviceTimestamp")));
            call.setDoctorId(c.getString(c.getColumnIndex("doctorId")));
            call.setSignature(c.getString(c.getColumnIndex("signature")));
            call.setSigSentFlag(c.getString(c.getColumnIndex("sigSentFlag")));
            call.setTimeSpent(c.getString(c.getColumnIndex("timeSpent")));
            call.setSentFlag(c.getString(c.getColumnIndex("sentFlag")));
            call.setCoordinates(c.getString(c.getColumnIndex("coordinates")));

            calls.add(call);

        } while (c.moveToNext());
    }

    c.close();
    db.close();

    return calls;
}

ご覧のとおり、最初の行で既に open() を呼び出していますが、データベースが既に閉じられていることを示すエラーが表示されます。スタック トレースは次のとおりです。

 java.lang.IllegalStateException: database    
 /data/data/com.***.****/databases/****.db (conn# 0) already closed
 at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2123)
 at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:398)
 at android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:390)
 at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:74)
 at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:311)
 at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:292)
 at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:156)
 at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:233)
 at com.***.****.datalayer.ESCAndroidDataLayer.getUnsentCalls(ESCAndroidDataLayer.java:5340)
 at com.***.****.synchall.SynchAll$UnsentSignatureSender.run(SynchAll.java:1750)

繰り返しになりますが、上記のメソッドは Thread クラスで呼び出されます。SQLite が自動的に閉じられることに関するリンクを見つけましたが、彼の解決策がわかりません: http://darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed-automatically.html

4

1 に答える 1

0

c.moveToFirst()の前にdb.acquireReference( )を呼び出してみてください

    db.acquireReference();

    if (c.moveToFirst()) {

または、db.close()を「 if(db.isOpen()) 」で囲むだけで十分な場合もあります。

    if (db.isOpen())
    {
        db.close();
    }

よくわかりませんが、これらは何かを変えるでしょう。

于 2012-06-21T06:05:21.767 に答える