Необходимо ли закрыть базу данных? - PullRequest
13 голосов
/ 11 февраля 2011

В примере Google Notepad они, похоже, не закрывают базу данных, по крайней мере, не в onDestroy ().

Какова цель ее закрытия, и мне действительно нужно?Открытая база данных занимает много памяти?Я обнаружил, что закрытие его в onDestroy оставляет уязвимости, если есть какие-либо запущенные потоки, которые могут попытаться получить к нему доступ после завершения действия.

Ответы [ 2 ]

11 голосов
/ 13 февраля 2011

Если вы не закроете соединения с базой данных, со временем они вызовут утечки памяти.

Пример Notepad использует startManagingCursor, но вам все равно нужно явно закрыть соединение с БД. Запустите пример Notepad как есть и отредактируйте несколько заметок подряд, вы увидите, что он начинает выдавать предупреждения и ошибки в LogCat. (В более крупных приложениях вы также начнете видеть предупреждения об обнаружении утечки памяти.)

W/SQLiteCompiledSql(  302): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: INSERT INTO notes(body, title) VALUES(?, ?);
W/SQLiteCompiledSql(  302): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
W/SQLiteCompiledSql(  302):     at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62)
...
W/SQLiteCompiledSql(  302):     at dalvik.system.NativeStart.main(Native Method)
E/Database(  302): close() was never explicitly called on database '/data/data/com.android.demo.notepad3/databases/data' 
E/Database(  302): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
E/Database(  302):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
...
E/Database(  302):  at dalvik.system.NativeStart.main(Native Method)

Вы упомянули, что закрытие его в onDestroy() "оставляет уязвимости" в любых потоках не-пользовательского интерфейса, которые еще работают. Если вы используете AsyncTask, вы можете проверить состояние этих потоков, используя getStatus в ваших задачах.

if ( myAsyncTask.getStatus() == AsyncTask.Status.FINISHED ){
    mDbHelper.close();
}

Затем закройте соединение в методе onPostExecute вашего AsyncTask.

Надеюсь, это поможет ...

0 голосов
/ 11 февраля 2011

Вы должны закрыть его.

В примере блокнота следует использовать Activity startManagingCursor .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...