2011-12-16 11 views
9

He buscado los registros de la base de datos usando Cursor. Es un trabajo perfecto. Pero, tengo algunos errores en Logcat mientras estoy usando el código¿Cómo cierro el Cursor y la Base de Datos de forma segura?

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

Mi Logcat es -

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) 

I referido algo de here. Dijeron que usan getReadableDatabase(). Estoy usando ese método también. Y, también he utilizar este método,

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

después de que el tener error como -

Database wasn't open. 

Después, también me has esto errores en mi base de datos. Entonces, ¿alguien me dice cómo adquirir el cierre de seguridad para el Cursor y la Base de Datos después de obtener los registros?

Respuesta

9

EDIT: Si devuelve un cursor que ya está cerrado, no puede usarlo. Abra la base de datos antes de llamar al método, luego cierre el cursor y luego la base de datos después de llamar al método.

Puede cerrar el cursor después de que haya terminado con él de esta manera:

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

O si usted está utilizando el cursor de una actividad, y la necesidad de volver a consultar (cuando se reinicia la actividad, se detuvo ...) se puede utilizar este:

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

Para cerrar la base de datos (después de cerrar el cursor, o si dentro de una actividad en onDestroy() de preferencia):

dbhelper.close(); 
1

También puede consultar este answer (sugiere dónde debe cerrar las conexiones de cursores/objetos de db dependiendo del estado de la actividad) o this one (sugiere cómo cerrar el objeto de SQLiteDatabase). No es necesario elaborar cuando ya está escrito una vez. A pesar de eso, a continuación se presenta una idea para la parte de codificación.

if (dbCursor != null && dbCursor.moveToFirst()) { 
      try { 
           //do stuff 
      } catch (exceptions) { 
           //catch possible exceptions 
      } finally { 

       if (dbCursor != null && !dbCursor.isClosed()) { 
        dbCursor.close(); 
       } 
      } 
+2

Esto cierra el cursor, no la base de datos. –

+0

sí - ¿has leído la última parte de la pregunta? Para citar: Entonces, ¿quién me dice cómo adquirir el cierre de seguridad para el Cursor y la Base de datos después de obtener los registros? – hovanessyan

1

cada vez que se llama a este método de base de datos se abrirá en modo de lectura usted, pero usted no cierre la base de datos que es por eso que conseguir este error. abrir una sola vez, como de método onCreate() y cierre en destroy()

mientras que se puede cerrar el cursor después de ir a buscar las filas y cuando no hay más necesidad de cursor continuación, cierre y configurado en nulo

2

mejor práctica sería- abrirlo en onResume() y cerrarlo en onPause().

+2

¿Alguna referencia a docs/examples? – Mixaz

3

En su clase que extiende ContentProvider, si está abriendo la conexión de base de datos y configurando el helper como una variable de instancia en onCreate, puede cerrar la conexión de base de datos en el cierre.

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

Trate de pasar SQLiteDatabase como un parámetro para el método de fetchAll:

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