Несколько вопросов о курсах базы данных SQLite в Android

Чтобы реализовать доступ к базе данных в моем приложении, я последовал за учебником Ларса Фогеля , но я очень смущен несколькими вещами …

1) Каждый раз при вызове fetchTodo будет создан и возвращен новый курсор. Оставить предыдущий курсор для сборщика мусора. Итак, если я не использую startManagingCursor или даже CursorLoader , следует ли мне называть .close() на курсоре, когда я покончу с этим? Конечно, вне области fetchTodo , например:

 Cursor cursor = mNotesAdapter.fetchTodo(); // do something... cursor.close(); 

Я закончил с этим курсором, и новый будет создан при следующем извлечении, должен ли я закрыть его таким образом, или я должен оставить его для сборщика мусора? Хотя я думаю, что я говорю о двух вещах, совершенно разных … То есть, я должен закрыть его, как в примере выше, или нет?

2) Cursor также имеет метод .deactivate() и в документации говорится, что он использует меньше ресурсов (чем активные курсоры). Когда я должен это использовать? Например, в моем приложении у меня есть ListActivity который заполняется через SimpleCursorAdapter (инициализация кода для этого вызывается только один раз). Используемый курсор – это переменная-член класса, потому что я нуждаюсь в ней вне метода, который заполняет список. Мне нужно, чтобы он запрашивал базу данных, когда что-то было удалено из нее. Но до тех пор, пока запись не будет удалена, это действие пользователя и может занять некоторое время, должен ли я отключить курсор тем временем? Потому что он снова будет активным, когда я снова вызову .requery() . Или SimpleCursorAdapter перестанет работать, потому что курсор не активен?

EDIT: я только что проверил этот и выяснил, что после настройки адаптера курсора я не могу вызвать deactivate() . Список будет пустым, если курсор не активен, поэтому он должен оставаться активным до тех пор, пока отображается ListActivity. В конце концов, мы должны просто позволить StartManagingCursor обрабатывать его. Или новый CursorLoader .

3) Я знаю, что startManagingCursor / stopManagingCursor устарел, но я не stopManagingCursor Honeycomb (по крайней мере, пока), и сейчас я не хочу иметь дело с новым CursorLoader . Но в учебнике выше, startManagingCursor используется везде, но stopManagingCursor никогда не вызывается один раз. Почему нет? Поддерживает ли Android это по-своему? Любая ситуация, которую я должен назвать stopManagingCursor ?

Изменить: обновленный ответ, чтобы отразить обновленный вопрос 1:

1) Каждый раз при вызове fetchTodo будет создан и возвращен новый курсор. Оставить предыдущий курсор для сборщика мусора. Итак, если я не использую startManagingCursor или даже CursorLoader, следует ли мне называть курсор .close () на курсоре, когда я покончу с этим?

Да, вы должны определенно сказать Android для startManagingCursor() , использовать LoaderManager / CursorLoader или close() его самостоятельно. Не делать этого будет утечка памяти, GC не поможет с этим, поскольку есть внутренние ресурсы за Cursor (например, файлы обрабатываются в базе данных).

2) Курсор также имеет метод .deactive (), и в документации говорится, что он использует меньше ресурсов (чем активные курсоры). Когда я должен это использовать?

EDIT для других читателей: OP нашел ответ и разместил его в своем вопросе. До сих пор сохраняется следующее:

Я никогда не использовал deactivate() (нет deactive() ), может быть, кто-то еще может это объяснить. Если вы хотите действительно безболезненный запрос / обновления, проверьте структуру LoaderManager – это не только для Honeycomb: с помощью библиотеки LoaderManager вы можете использовать LoaderManagerFragments ) до Android 1.6. Это не только код для вас, но и полностью выгружает эти вещи на Android, гораздо больше, чем startManagingCursor() .

EDIT2: некоторые заметки о LoaderManager

Есть учебники LoaderManager на developer.android.com, но они довольно … сложны и трудно понять в первый раз, как и большинство учебных пособий. Мне также пришлось много копать, лучшая остановка «все-в-одном», которую я нашел до сих пор, – http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/ (плюс все javadocs и источник совместимости lib Вы можете найти), то, как работает LoaderManager очень похож на управляемые диалоги (теперь также устаревшие, замененные DialogFragment ) с помощью их onCreateDialog , onPrepareDialog где вы просто onPrepareDialog Android на «show dialog # 123», а затем Android вызывает ваши Код с этим идентификатором; onCreateLoader() же самое для загрузчиков: «load loader # 123», Android вызывает onCreateLoader() .

Единственный очевидный недостаток изначально состоит в том, что LoaderManager значительной степени опирается на структуру ContentProvider и некоторые люди, похоже, действительно им не нравятся. Конечно, это дополнительное обучение и код, но как только у вас есть ContentProvider для ваших собственных данных (даже если он используется только в частном порядке в вашем приложении), все привязки данных к виду – это легкий ветерок с CursorLoader . ИМХО, есть небольшая разница между качению свой собственный «контент – провайдер» и на самом деле реализации ContentProvider – но это только мое мнение весьма спорно 🙂

3) Я знаю, что startManagingCursor / stopManagingCursor устарел, но я не настраиваю Honeycomb (по крайней мере, пока), и сейчас я не хочу иметь дело с новым CursorLoader. Но в учебнике выше, startManagingCursor используется везде, но stopManagingCursor никогда не вызывается один раз. Почему нет? Поддерживает ли Android это по-своему? Любая ситуация, которую я должен назвать stopManagingCursor?

Когда вы вызываете startManagingCursor() Cursor больше не является вашей проблемой. Android позаботится о том, чтобы закрыть Курсор, когда ваша Activity будет уничтожена (пользователь переходит в сторону, изменение ориентации, …). Нет необходимости сопоставлять вызов startManagingCursor() с вызовом stopManagingCursor() – вы обычно не хотите брать на себя бремя управления Cursor снова, как только вы избавитесь от него.

Intereting Posts
Android: изменение раскрывающегося списка Spinner Как остановить / запустить службу, содержащую бесконечный цикл при создании Сколько Android-устройств поддерживает GLSurfaceView.setPreserveEGLContextOnPause сегодня? NPE: CursorTreeAdapter $ MyCursorHelper.changeCursor (Cursor, boolean) 'для ссылки на нулевой объект Как очистить сохраненную ценность LiveData? Как отобразить форматированный текст в формате HTML в поле PopUp с помощью диалогового окна создания предупреждений? Как я могу передавать музыку из файла внутри зашифрованного zip без распаковки всего файла? Android SDK Manager, локальная копия пакетов Кинжал 2 с Android Studio 3.0 Preview (Canary 2) с использованием аннотации Processor вместо android-apt Функция Talkback RecyclerView не очень хорошо Проблема с андроидом Edittext Com.android.ddmlib.AdbCommandRejectedException: устройство в автономном режиме (даже если устройство подключено) Как исправить ошибки в автогенерированном файле IMarketBillingService.java? Как использовать общие снимки моментальных снимков элемента во время перехода на активность? Android RelativeLayout поддерживает