Come faccio a chiudere il Cursore e Database in modo sicuro?

Ho recuperato i record dal Database utilizzando il Cursore. E ‘ un lavoro perfetto. Ma ho alcuni errori nel Logcat, mentre io sto utilizzando questo codice

public Cursor fetchAll()
{
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior); 
    return cursor;
}

Mio logcat è –

12-16 14:49:20.774: E/Database(18611): close() was never explicitly called on database '/data/data/com.android.application/databases/appZ.db' 
12-16 14:49:20.774: E/Database(18611): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
12-16 14:49:20.774: E/Database(18611):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
12-16 14:49:20.774: E/Database(18611):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
12-16 14:49:20.774: E/Database(18611):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.DBHelper.fetchAll(DBHelper.java:91)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.ApplicationActivity.sc_adapter(ApplicationActivity.java:1210)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.ApplicationActivity.refresh_data(ApplicationActivity.java:1195)
12-16 14:49:20.774: E/Database(18611):  at com.android.todoapplication.ApplicationActivity.onKeyDown(ApplicationActivity.java:1440)
12-16 14:49:20.774: E/Database(18611):  at android.view.KeyEvent.dispatch(KeyEvent.java:1037)
12-16 14:49:20.774: E/Database(18611):  at android.app.Activity.dispatchKeyEvent(Activity.java:2068)
12-16 14:49:20.774: E/Database(18611):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
12-16 14:49:20.774: E/Database(18611):  at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
12-16 14:49:20.774: E/Database(18611):  at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
12-16 14:49:20.774: E/Database(18611):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
12-16 14:49:20.774: E/Database(18611):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-16 14:49:20.774: E/Database(18611):  at android.os.Looper.loop(Looper.java:123)
12-16 14:49:20.774: E/Database(18611):  at android.app.ActivityThread.main(ActivityThread.java:4627)
12-16 14:49:20.774: E/Database(18611):  at java.lang.reflect.Method.invokeNative(Native Method)
12-16 14:49:20.774: E/Database(18611):  at java.lang.reflect.Method.invoke(Method.java:521)
12-16 14:49:20.774: E/Database(18611):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-16 14:49:20.774: E/Database(18611):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-16 14:49:20.774: E/Database(18611):  at dalvik.system.NativeStart.main(Native Method)

Ho riferito qualcosa da qui. Hanno detto che l’uso getReadableDatabase(). Io sto usando quel metodo anche. E mi è capitato anche di usare questo metodo,

public Cursor fetchAll()
{
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior); 
   if (cursor!=null)
    {
        cursor.close();
    }
   if (db!=null)
    {
        db.close();
    }
    return cursor;
}

dopo di che errore come –

Database wasn't open.

Dopo, anche io ho questo errore nel mio Database. Quindi, qualcuno mi sa dire Come faccio ad acquisire la sicurezza prossimità del Cursore e Database dopo il recupero record.

InformationsquelleAutor Praveenkumar | 2011-12-16



6 Replies
  1. 10

    EDIT: Se si restituisce un cursore che è già chiusa, non è possibile utilizzarlo. Aprire il database prima di chiamare il metodo, quindi chiudere il cursore e quindi il database dopo la chiamata al metodo.

    È possibile chiudere il cursore dopo che hai finito con esso come questo:

    Cursor cursor = fetchAll();
    ... //Do your work with the cursor
    cursor.close();

    Oppure, se si utilizza il cursore da un’attività, e la necessità di requery (quando l’attività è riavviato, si è fermato…) si può usare questo:

    Cursor cursor = fetchAll();
    startManagingCursor(cursor); //Android will take care of the cursor for you
    //Do your work with the cursor

    Per chiudere il database (dopo la chiusura del cursore, o se all’interno di un’attività in onDestroy() di preferenza):

    dbhelper.close();
    • Questa soluzione funziona per me. Grazie, @Noureddine 🙂
  2. 3

    Nella tua classe che estende ContentProvider, se si apre la connessione al database
    e l’impostazione helper come una variabile di istanza onCreate, è possibile chiudere il
    connessione al database in arresto.

    @Override
    public boolean onCreate() {
        mOpenHelper = getDBOpenHelper(); 
        return true;
    }
    @Override
    public void shutdown() {
    mOpenHelper.close();
        super.shutdown();
    }
  3. 2

    Pratica migliore sarebbe aprire in onResume() e chiudere in onPause().

    • Tutti i riferimenti a documenti e/o esempi?
  4. 1

    ogni volta quando si chiama questo metodo di database viene aperto in modalità di lettura, ma voi non chiudere il database che è il motivo di questo errore. aperto solo una volta, come da onCreate() metodo e destroy()

    mentre è possibile chiudere il cursore dopo il recupero righe e quando non c’è più bisogno per spostare il cursore, quindi chiudere e impostare a null

  5. 1

    Si può anche fare riferimento a questa risposta (suggerisce dove si dovrebbe chiudere i cursori/db oggetti connessioni a seconda dello stato di Attività) o questo (suggerisce come chiudere SQLiteDatabase oggetto). Non c’è bisogno di elaborare quando è già scritto una volta. Nonostante che, di seguito, idea per la parte di codifica.

        if (dbCursor != null && dbCursor.moveToFirst()) {
                try {
                                  //do stuff
                }  catch (exceptions) {
                                  //catch possible exceptions
                } finally {
    
                    if (dbCursor != null && !dbCursor.isClosed()) {
                        dbCursor.close();
                    }
                }
    • Questo chiude il cursore, non il database.
    • sì, avete letto l’ultima parte della domanda? Citazione: Quindi qualcuno mi sa dire Come faccio ad acquisire la sicurezza prossimità del Cursore e Database dopo il recupero record.
  6. 0

    Prova a passare SQLiteDatabase parametro fetchAll metodo:

    MyDatabase db = new MyDatabase(this);
    
    ....
    
    Cursor myCursor = db.fetchAll(db.getReadableDatabase());
    
    myCursor.close();
    db.close();
    
    
    
    
        public Cursor fetchAll(SQLiteDatabase db, String listName) {
            String sql = "select ID _id, Name from ListName where Name = ? order by ID";
            Cursor c = db.rawQuery(sql, new String[] { listName });
            c.moveToFirst();
    
            return c;
        }

Lascia un commento