2012-04-10 5 views
2

schließt das Android-System automatisch eine offene SQLite-Datenbank? Ich habe eine Singleton-Klasse für den Zugriff auf Daten implementiert und manchmal müssen die Methoden dort auf einem Arbeitsthread ausgeführt werden. Ich habe eine Synchronisations-Funktionalität bei Abfragen, die auf dem Hintergrund ausgeführt werden, hier ist der Code:Android: FC beim Abfragen von SQLite geöffnete Datenbank

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; 
} 

Wie Sie sehen können, habe ich schon offen genannt() auf den ersten Zeilen noch bin ich eine Fehlermeldung erhalten, die sagt dass meine Datenbank bereits geschlossen ist. Hier ist der Stack-Trace:

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) 

Auch das Verfahren, das oben auf einer Thread-Klasse aufgerufen wird, wenn das hilft. Ich habe einen Link in Bezug auf SQLite gefunden automatisch geschlossen wird, aber ich verstehe nicht seine Lösung: http://darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed-automatically.html

Antwort

0

Try db.acquireReference() vor c.moveToFirst()

db.acquireReference(); 

    if (c.moveToFirst()) { 

oder es nennen kann ausreichen, einfach db.close() mit "if (db.isOpen())" einzuschließen.

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

Ich bin nicht so sicher, aber diese werden etwas ändern.

+0

Ich habe eine Location Fetcher arbeitet im Hintergrund, holt einen Speicherort und speichert es dann in der DB. Ich bin mir jedoch nicht sicher, ob dies meine anderen Datenbankzugriffe beeinflussen kann, wenn es zufällig gleichzeitig passiert. –