Я знаю, что это было обсуждено, но я хотел спросить о текущем состоянии дел. Нужно ли создавать ContentProvider для использования CursorLoader в связи с базой данных sqlite?
Я нашел
Использование CursorLoader без ContentProvider
Выглядит точно, на что я надеялся, пока комментирует Emmby
Так упоминается другое решение
https://github.com/commonsguy/cwac-loaderex
опять же указывается некоторый недостаток
Конечно, при использовании LoaderManager мы хотим получить все преимущества, для которых он был введен. Поэтому мой вопрос заключается в том, есть ли способ использовать LoaderManager в связи с базой данных sqlite без необходимости реализации поставщика контента, но при этом есть все преимущества.
Спасибо
В двух реализациях, которые вы упомянули в своем посте, предлагаются все преимущества CursorLoader
кроме возможности получать уведомления при изменении базового содержимого.
Недавно я много изучал этот вопрос, и я могу с уверенностью сказать вам, что API Android в настоящее время не предоставляет средства для этого только с помощью raw SQLiteDatabase
(он предоставляет только ContentResolver#notifyChange()
и Cursor#setNotificationUri()
, которые используются для уведомления всех Cursor
, зарегистрированных под определенным уведомлением Uri
).
Тем не менее, ваши варианты прямо сейчас:
Внедрение самого наблюдателя, способного получать уведомления от SQLiteDatabase
при изменении содержимого и каким-то образом разрешать эти уведомления для всех существующих Loader
в вашем приложении. Я написал довольно обширное сообщение в блоге о том, как реализовать Loader
, который может пригодиться, если вы хотите принять по этой проблеме. Или...
Используйте библиотеку Mark Murphy LoaderEx
и делайте изменения базы данных только с помощью операций AsyncTask
, которые предоставляет его библиотека. Обратите внимание, что причина, по которой его задачи обновляют Loader
, состоит в том, что они вызывают onContentChanged
на Loader
сразу после выполнения вставки/обновления/удаления, эффективно сообщая Loader
, что содержимое изменилось, и что оно должно обновите его данные.
Просто используйте ContentProvider
с CursorLoader
, и вы можете использовать метод ContentResolver#notifyChange()
для уведомления CursorLoader
о том, что произошло изменение содержимого.
Я пытаюсь найти лучшее решение, и я буду сообщать в будущем, если я когда-либо его найду/внедрю, но сейчас это нужно будет сделать.
Вот мое решение, в моем onCreateLoader
{
Uri u = Uri.parse("content://what_string_you_want");
return new CursorLoader(this, yourURI, projection, null, null, null) {
private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
@Override
public Cursor loadInBackground() {
Cursor c = YOUR_DATABASE.doYourQuery(...);
if (c != null) {
// Ensure the cursor window is filled
c.getCount();
c.registerContentObserver(mObserver);
}
c.setNotificationUri(getContext().getContentResolver(), getUri());
return c;
}
};
}
После кода, который изменит БД, добавьте
getContentResolver().notifyChange(
Uri.parse("content://same_with_first_string"), null);