Несколько вопросов о курсорах баз данных SQLite в Android - PullRequest
6 голосов
/ 30 сентября 2011

Чтобы реализовать доступ к базе данных в моем приложении, я следовал учебнику Lars Vogel , но я очень запутан в некоторых вещах ...

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

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

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

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

РЕДАКТИРОВАТЬ: Я только что проверил это и обнаружил, что я не могу позвонить deactivate() после настройки адаптера курсора. Список будет пустым, если курсор не активен, поэтому он должен оставаться активным до тех пор, пока отображается ListActivity. В конце мы должны просто позволить StartManagingCursor обработать это тогда. Или новый CursorLoader.

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

1 Ответ

9 голосов
/ 30 сентября 2011

Редактировать: обновленный ответ для отражения обновленного вопроса 1:

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

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

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

РЕДАКТИРОВАТЬ другим читателям: ОП нашел ответ и разместил его в своем вопросе. Следующее остается в силе:

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

EDIT2: некоторые примечания по LoaderManager

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

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

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

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

...