Quantcast
Channel: Out Of What Box?
Viewing all articles
Browse latest Browse all 10

Android: Closing those database objects

$
0
0
(Or, what the Notepad tutorial never told you.)

If you’ve used Android’s Notepad tutorial (Version 3) , or modeled your own Activity on Notepadv3, then you’ve probably seen log messages that look something like this:

android.database.sqlite.DatabaseObjectNotClosedException: 
    Application did not close the cursor or database object that was opened here
at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:36)
at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1145)
at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1671)
at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1622)
at com.android.demo.notepad3.NotesDbAdapter.updateNote(NotesDbAdapter.java:186)
at com.android.demo.notepad3.NoteEdit.saveState(NoteEdit.java:106)
at com.android.demo.notepad3.NoteEdit.onPause(NoteEdit.java:87)
at android.app.Activity.performPause(Activity.java:3842)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1190)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3335)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3305)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3288)
at android.app.ActivityThread.access$2500(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2044)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)

This is resolved easily enough by overriding the onDestroy method in each of the Activities in your application — or at least, each Activity that uses the database. In the Notepadv3 app, this means overriding onDestroy in both the Notepadv3 and NoteEdit classes. The same definition is suitable for both classes:

    public void onDestroy() {
        super.onDestroy();

        // Replace mDbHelper as needed with your database connection, or
        // whatever wraps your database connection. (See below.)
        mDbHelper.close();
    }

In the Notepadv3 tutorial, the mDbHelper field is an instance of the class NotesDbAdapter, which wraps the database connection. NotesDbAdapter comes from google with the close method already defined, but there’s no code that calls it. With this change, we’re supplying the code that calls close at the right time. (I think.)

In general: If your activity opens a database by calling either SQLiteOpenHelper.getReadableDatabase or SQLiteOpenHelper.getWritableDatabase, then you should rely on SQLiteOpenHelper.close to close that database. Your activity’s onDestroy method must result in a call to the close method for any instances of SQLiteOpenHelper, or classes derived from it, that you’ve created. (In the code above, mDbHelper.close will have that effect.) SQLiteOpenHelper.close will then close any database handle that it created for you.


Viewing all articles
Browse latest Browse all 10

Latest Images

Trending Articles



Latest Images