#android #android-strictmode
#Android #android-strictmode
Вопрос:
Я пытался запустить свое приложение в StrictMode, чтобы проверить наличие какой-либо скрытой проблемы, которая могла возникнуть. Одна из проблем, с которой я столкнулся, — это то, что кажется ложным срабатыванием из-за утечки подключений к базе данных при использовании ContentResolver.
После некоторых экспериментов проблема была упрощена до следующих двух строк кода:
Cursor c = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, cols, null, null, MediaStore.Video.Media.DEFAULT_SORT_ORDER);
c.close()
Приведенные выше 2 строки приводят к следующему нарушению StrictMode:
ERROR/StrictMode(26219): Releasing cursor in a finalizer. Please ensure that you explicitly call close() on your cursor:
ERROR/StrictMode(26219): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
ERROR/StrictMode(26219):
at android.database.CursorWindow.<init>(CursorWindow.java:62)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:403)
at android.content.ContentResolver.query(ContentResolver.java:302)
Я предполагаю, что это связано с тем, что курсор был возвращен ContentProvider (так что это не прямой курсор SQLite).
Есть ли у кого-нибудь представление о том, действительно ли это ложное срабатывание или действительно курсор протекает.
Комментарии:
1. Я вижу нечто подобное, используя CursorLoader API, выпущенный с Honeycomb. У меня есть CursorLoader (который выполняет запрос в фоновом потоке) и SimpleCursorAdapter. В принципе, SimpleCursorAdapter должен закрывать любой существующий курсор, когда я заменяю его новым из CursorLoader. Тем не менее, я продолжаю видеть эти нарушения режима StrictMode для завершения курсора, так что это немного озадачивает.
Ответ №1:
Я думаю, что могу объяснить, в чем проблема. При запросе базы данных вы можете получить исключение. Таким образом, будет создан курсор c.close() не будет вызван, поскольку существует исключение. Таким образом, вы должны поместить создание курсора в блок try catch и закрыть курсор в блоке finally.