5

Sono perplesso su ciò che sta causando questo errore, in quanto ho fatto in modo che sto chiudendo la mia scheda di database correttamente (almeno penso di essere). Ecco cosa dice di LogCat (il tag per tutti loro è AndroidRuntime):IllegalStateException: database già chiuso (utilizzando ViewPager)

irreversibile: main java.lang.IllegalStateException: banca dati /data/data/com.acedit.assignamo/databases/data.db (conn # 0) già chiuso su android.database.sqlite.SQLiteDatabase.verifyDbIsOpen (SQLiteDatabase.java:2082) su android.database.sqlite.SQLiteDatabase.lock (SQLiteDatabase.java:413) su android.database.sqlite. SQLiteDatabase.lock (SQLiteDatabase.java:400) su android.database.sqlite.SQLiteQuery.fillWindow (SQLiteQuery.java:79) su android.database.sqlite.SQLiteCursor.fillWindow (SQLiteCursor.java:164) su e roid.database.sqlite.SQLiteCursor.onMove (SQLiteCursor.java:147) su android.database.AbstractCursor.moveToPosition (AbstractCursor.java:178) su android.support.v4.widget.CursorAdapter.getItemId (CursorAdapter.java: 225) su android.widget.AbsListView.onSaveInstanceState (AbsListView.java:1569) su android.view.View.dispatchSaveInstanceState (View.java:9868) su android.view.ViewGroup.dispatchFreezeSelfOnly (ViewGroup.java:2310) a android.widget.AdapterView.dispatchSaveInstanceState (AdapterView.java:770) a android.view.ViewGroup.dispatchSaveInstanceState (ViewGroup.java:2296) a android.view.View.saveHierarchyState (View.java:9851) a android.support.v4.app.FragmentManagerImpl.saveFragmentViewState (Fragme ntManager.java:1561) su android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:962) su android.support.v4.app.FragmentManagerImpl.detachFragment (FragmentManager.java:1233) su android. support.v4.app.BackStackRecord.run (BackStackRecord.java:620) su android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:1431) su android.support.v4.app.FragmentManagerImpl.executePendingTransactions (FragmentManager.java:431) su android.support.v4.app.FragmentPagerAdapter.finishUpdate (FragmentPagerAdapter.java:141) su android.support.v4.view.ViewPager.populate (ViewPager.java:895) su android. support.v4.view.ViewPager.populate (ViewPager.java:772) su android.support.v4.vi ew.ViewPager.completeScroll (ViewPager.java:1539) su android.support.v4.view.ViewPager.computeScroll (ViewPager.java:1422) su android.view.View.getDisplayList (View.java:10406) presso android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) su android.view.View.getDisplayList (View.java:10380) su android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) su Android. view.View.getDisplayList (View.java:10380) su android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) su android.view.View.getDisplayList (View.java:10380) su android.view. ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) su android.view.View.getDisplayList (View.java:10380) su android.view.HardwareRenderer $ GlRenderer.draw (HardwareRenderer.java:875) su android.view.ViewRootImpl.draw (ViewRootImpl.java:1910) su android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1634) a android.view.ViewRootImpl.handleMessage (ViewRootImpl.java:2442) a android.os.Handler.dispatchMessage (Handler.java:99) a android.os.Looper.loop (Looper.java:137) a android.app.ActivityThread.main (ActivityThread.java:4575) all'indirizzo java.lang.reflect.Method.invokeNative (metodo nativo) in java.lang.reflect.Method.invoke (Method.java:511) in com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:786) in com .android.internal.os.ZygoteInit.main (ZygoteInit.java:553) a dalvik.system.NativeStart.main (Native Method)

Il mio codice:

public Cursor fetchIncompleteAssignments(Short course) { 
    DbAdapter adapter = new DbAdapter(context, null, Values.ASSIGNMENT_TABLE); 
    adapter.open(); 

    Cursor r; 
    if (course == null) // Fetching from all courses 
     r = adapter.fetchAllWhere(Values.ASSIGNMENT_LIST_FETCH, Values.ASSIGNMENT_KEY_STATUS + "=" + 0, Values.ASSIGNMENT_KEY_DUE_DATE); 
    else 
     r = adapter.fetchAllWhere(Values.ASSIGNMENT_LIST_FETCH, Values.ASSIGNMENT_KEY_COURSE + "=" + course 
      + " AND " + Values.ASSIGNMENT_KEY_STATUS + "=" + 0, Values.ASSIGNMENT_KEY_DUE_DATE); 
    adapter.close(); 
    return r; 
} 

// Part of DbAdapter: 
public DbAdapter open() throws SQLException { 
    dbHelper = new DatabaseHelper(context); 
    db = dbHelper.getWritableDatabase(); 
    return this; 
} 

public void close() { 
    if (db != null) { 
     try { 
      db.close(); 
      dbHelper.close(); 
     } catch (NullPointerException e) { 
      Log.e("Close", "Error: " + e + " " + e.getMessage()); 
     } 
    } else 
     Log.e("Close", "Error! db \"" + DATABASE_TABLE + "\" is null."); 
} 

Il Cursor tornato da fetchAllAssignments() viene utilizzato per popolare uno ListView tramite un numero personalizzato CursorAdapter. Lo ListView è il contenuto di ListFragment e vi sono più istanze di questa ListFragment visualizzate in ciascuna pagina di un ViewPager (una per mostrare i compiti di tutti i corsi e quindi una pagina per ciascuno dei singoli corsi).

Qualche idea su cosa è sbagliato? Per quanto ne so, sto chiudendo il mio database correttamente. Fammi sapere se hai bisogno di più codice. Grazie in anticipo!

MODIFICA: I dati vengono estratti dal database bene e popola anche il ListView. Posso scorrere le varie pagine, ma sembra bloccarsi ogni volta che il frammento viene fermato. Spesso si blocca quando avvio un'altra attività, ma non sempre. Occasionalmente si romperà anche quando sto scorrendo le pagine, anche se molto raramente. Ecco il mio metodo onPause() per il mio Fragment (non ho un onStop() o OnDestroy()):

public void onPause() { 
    super.onPause(); 
    if (!assignmentsCursor.isClosed()) { 
     assignmentsCursor.close(); 
     assignmentsCursor = null; 
    } 
} 

Nel mio onResume() ho solo ricaricare la lista dal database e ottenere una nuova copia del contesto via getActivity(). Forse qualcosa viene cancellato (a scopo di memoria) e non lo sto ricaricando? Non ricevo alcun tipo di NullPointerException, quindi mi sembra improbabile che ...

risposta

3

questa eccezione viene effettivamente sollevata perché si chiude il database in due, non perché non lo si chiude.

così ..

in voi close() metodo, sostituire la seguente riga nel codice:

if (db != null) { 

con:

if (db != null && db.isOpen()) { 
+0

Sì, questo sicuramente rende più sensate tutte le risposte. Non ho mai pensato di farlo comunque. :) – mightimaus

+0

grazie @ EverythingTech96, se questo ha risolto il tuo problema, fammi sapere. – kdehairy

2

Crea il tuo DbHelper un singleton, come descritto in this post.

+0

penso che ha aiutato. Si blocca ancora occasionalmente, ma penso molto meno. Un buon consiglio comunque, grazie! :) Altre idee? – mightimaus

+0

Se hai reso il tuo 'DbHelper' un singleton, non dovresti chiuderlo. –

+0

Devo chiudere il mio 'SQLiteDatabase' (' db')? – mightimaus

Problemi correlati