Во-первых, позвольте мне описать мой случай: я получаю список категорий, которые заполняют RecyclerView
. Каждый View
в этом списке является своего рода виджетом, и наиболее распространенным является другой список (горизонтальный RecyclerView
) с некоторыми новостями (также анализируемыми от JSON).LoaderManager запускает все Погрузчики одновременно
Я сохраняю все в ContentProvider
и SQLiteDatabase
(с помощником), который содержит две таблицы - для категорий и новостей (каждый из них имеет ключ категории). Поэтому я использую Loader
для каждого виджета для загрузки данных из базы данных или, если они отсутствуют, я загружаю правильные данные и вставляю их в db. А затем загрузчик автоматически обновляет список, доставляя новый курсор.
Сразу же на экране могут отображаться два (или более) горизонтальных списка с новостями. Каждый из этих списков регистрации собственного Loader
как здесь:
loaderManager.initLoader(getWidgetCategory().getCategoryID(), null, getLoader());
под getLoader();
мы же Loader
(для виджетов с новостями), как показано ниже:
private class NewsLoader implements LoaderManager.LoaderCallbacks<Cursor> {
@Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
return new CursorLoader(getContext(),
CustomContract.News.CONTENT_URI,
CustomContract.News.PROJECTION_ALL,
CustomContract.News.KEY_CATEGORY_ID+"=?",
new String[]{String.valueOf(getWidgetCategory().getCategoryID())},
CustomContract.News.ORDER_BY_DEFAULT
);
}
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
if (data.getCount()>=15) {
swapCursor(data);
displayContent();
}
}
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
swapCursor(null);
}
}
, и проблема: когда я загрузить и вставить к новостям базы данных только из одной категории все Loader
s увольняют обновляющие списки, и это очень плохо для производительности ... Например - есть два горизонтальных списка с новостями на экране, мы прокручиваем бит вниз и еще один (третий) приближается. У него нет новостей, поэтому фоновая задача загружает их и вставляет в db, а затем LoaderManager
запускает Loader
для третьего виджета. НО не только ... Также Loaders
, прикрепленный к двум спискам выше, запускает обновление собственных списков.
Я предполагаю, что есть проблема с тем же CONTENT_URI
, может быть, другие параметры в CursorLoader
конструктора. Единственное изменение там (для каждого виджета горизонтального списка новостей) - это статья WHERE
с различным идентификатором категории, и все Loader
s получают контент из той же таблицы db. Как я могу уволить только один Loader
для виджета, который загружал/вставлял новости? Обратите внимание, что идентификатор зарегистрированного загрузчика и выбор WHERE
...
Как я уже писал, могут быть разные типы виджетов (а также списки, но не новости), которые заполняются из других таблиц и их Loader
s не стреляют с новостями Loader
s. Я предполагаю, что если я получу список категорий с только текстовыми виджетами (также общая таблица db), загрузка текста для одного из виджетов приведет к потере всех «Loader» и перерисовки других виджетов.
редактировать:
В других, коротких словах: в моем обычае ContentProvider
я перекрываться query
метод, который содержит строку:
@Override
public Cursor query(
final Uri uri,
final String[] projection,
final String selection,
final String[] selectionArgs,
String sortOrder
) {
//selection, etc.
//newly created cursor from selection above
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
и это уведомляющее все наблюдение Loader
с с прошедшим uri
. У меня мало списков (неважно, что это RecyclerView
s), которые потребляют данные из одного URI, но передают пользовательский параметр выбора для каждого CursorLoader
. Но URI является общим для всех, поэтому все загрузчики уведомляются, и я хочу уведомить только об этом, который активировал активность базы данных. Я хочу уведомить только один Loader
с известным идентификатором, который также передается методу query
внутри selectionArgs
. Да, я знаю, что это может быть невозможно внутри query
, но, возможно, другим способом?Для уведомления Loader
S не только их URI
Пожалуйста, разместите код, создающий 'CursorAdapter'. Используете ли вы параметр flags для регистрации ContentObserver? –
Игнорировать предыдущий комментарий, см. Мой ответ. –
Я думаю, что @alexlockwood должен взвесить на этом. –