Получение SQLiteCursorLoader для наблюдения за изменениями данных

Я пытаюсь реализовать DataListFragment с адаптером, который использует Loader от Commonsware. Этот загрузчик напрямую использует SQLiteDatabase и не требует использования ContentProviders.

Ссылка на android указывает на загрузчики: «Пока загрузчики активны, они должны отслеживать источник своих данных и предоставлять новые результаты при изменении содержимого».

В моей реализации SQLiteCursor (ниже) этого не происходит. OnLoadFinished() один раз и все. Предположительно, можно было бы вставить Loader.onContentChanged() где базовая база данных будет изменена, но в целом класс кода базы данных не знает о загрузчиках, поэтому я не уверен в том, как лучше всего это реализовать.

Есть ли у кого-нибудь какие-либо советы относительно того, как «знать данные загрузчика», или я должен обернуть материал базы данных в качестве ContentProvider и вместо этого использовать CursorLoader?

 import com.commonsware.cwac.loaderex.SQLiteCursorLoader; public class DataListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>{ protected DataListAdapter mAdapter; // This is the Adapter being used to display the list's data. public SQLiteDatabase mSqlDb; private static final int LOADER_ID = 1; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); int rowlayoutID = getArguments().getInt("rowLayoutID"); // Create an empty adapter we will use to display the loaded data. // We pass 0 to flags, since the Loader will watch for data changes mAdapter = new DataListAdapter(getActivity(),rowlayoutID, null , 0); setListAdapter(mAdapter); // Prepare the loader. Either re-connect with an existing one, // or start a new one. LoaderManager lm = getLoaderManager(); // OnLoadFinished gets called after this, but never again. lm.initLoader(LOADER_ID, null, this); } public Loader<Cursor> onCreateLoader(int id, Bundle args) { String sql="SELECT * FROM "+TABLE_NAME+";"; String[] params = null; SQLiteCursorLoader CursorLoader = new SQLiteCursorLoader(getActivity(), mSqlDb, sql, params); return CursorLoader; } public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the old cursor once we return.) mAdapter.swapCursor(data); // The list should now be shown. if (isResumed()) { setListShown(true);} else { setListShownNoAnimation(true); } } public void onLoaderReset(Loader<Cursor> loader) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. mAdapter.swapCursor(null); } 

Документация Loader имеет недостатки.

100% реализаций Loader встроенных в Android, «контролируют источник данных и дают новые результаты при изменении содержимого». Поскольку на данный момент только одна реализация Loader встроена в Android, их документация является точной, насколько это возможно.

Однако, цитируя обновление моей книги, которое должно быть выпущено через час или два:

В рамках, которые требуют такого поведения, нет ничего. Более того, есть некоторые случаи, когда явно плохая идея сделать это – представьте загрузку данных загрузчика из Интернета, и вам нужно постоянно опробовать какой-либо сервер, чтобы искать изменения.

Я планирую увеличить SQLiteCursorLoader чтобы как минимум немного узнать о изменениях в базе данных, если вы проложите все изменения базы данных через него. Это тоже будет иметь ограничения, поскольку вы не разделяете объекты Loader между действиями (не говоря уже о доступе к ним из служб).

Единственная причина, по которой CursorLoader работает так, как она есть, заключается в том, что она использует ContentProvider – синглтон, который может поэтому знать обо всех операциях.

В настоящий момент какая-либо часть вашего кода отвечает за вставки, обновления и удаления, либо нужно будет нажать на SQLiteCursorLoader на плечо и обновить его, либо уведомить об этом изменения (например, трансляцию из Service ), чтобы Активность может коснуться SQLiteCursorLoader на плече.