Подтвердить что ты не робот

Как CursorLoader с LoaderManager знает, как отправить курсор на CursorAdapter?

Я просматривал часть своего кода, и я понял, что на самом деле я не знаю, как комбинация CursorLoader и LoaderManager, используемая при подключении CursorAdapter. Это часть, с которой я запутался.

agendaAdapter = new MyAgendaAdapter(this, null);

makeProviderBundle(new String[] {"_id", "event_name", "start_date", "start_time",
    "end_date", "end_time", "location"}, "date(?) >= start_date and date(?) <= end_date", 
new String[]{getChosenDate(), getChosenDate()}, null);

getLoaderManager().initLoader(0, myBundle, MainDisplayActivity.this);
list.setAdapter(agendaAdapter);

Итак, как метод query() из моего пользовательского ContentProvider знает, чтобы отправить его этому конкретному CursorAdapter? Я просто не вижу связи. Я все понимаю в этом, но о том, что этот вопрос. О, и я должен упомянуть, код работает нормально.

4b9b3361

Ответ 1

Прежде всего, проверьте образец кода на этот пост и этот пост для более глубокого изучения того, как работает этот процесс.

И теперь, чтобы ответить на ваши вопросы...

Как метод query() из моего пользовательского ContentProvider...?

Хорошо, сначала помните, что getContentResolver().query() не вызывает метод контент-провайдера query напрямую. Вы вызываете метод запроса разрешения контента, который анализирует Uri, определяет поставщика, который вы хотите вызвать, а затем вызывает ваш провайдер query метод .

Как запрос отправляется на этот конкретный CursorAdapter?

Я расскажу вам о процессе, используя API Demos в качестве примера. Обратите внимание, что в демонстрационных версиях API вместо ListActivity используется ListFragment (разница не важна в контексте этого вопроса).


  • Сначала создайте (и настройте) CursorAdapter.

    mAdapter = new SimpleCursorAdapter(
            getActivity(),
            android.R.layout.simple_list_item_2, 
            null,
            new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
            new int[] { android.R.id.text1, android.R.id.text2 }, 
            0);
    

    После выполнения этого оператора SimpleCursorAdapter знает, как он должен связывать данные курсора с вашими представлениями. Независимо от того, какие данные в столбце курсора Contacts.DISPLAY_NAME будут связаны с представлением с id android.R.id.text1 и т.д.

    Обратите внимание, что вы передали курсор null в качестве третьего аргумента конструктору. Это очень важно, поскольку мы еще не задавали никаких данных (это задание LoaderManager и CursorLoader).

  • Затем инициализируйте загрузчик.

    getLoaderManager().initLoader(0, null, this);
    

    Это сообщает LoaderManager создать и запустить Loader, соответствующий id 0.

  • LoaderManager вызывает onCreateLoader(int id, Bundle args).

    onCreateloader возвращает подкласс интерфейса Loader<Cursor> (т.е. a CursorLoader, в этом случае). Этот CursorLoader будет выполнять первоначальный запрос и будет обновляться при изменении данных.

    Если ваша активность/фрагмент имеет более одного загрузчика, вы должны использовать switch(id), чтобы определить, какой конкретный загрузчик получил указание начать процесс загрузки.

  • Запрошенный курсор передается в onLoadFinished().

    Сразу после того, как CursorLoader создается и возвращается на шаге 3, CursorLoader выполняет первоначальный запрос в отдельном потоке и возвращает курсор. Когда CursorLoader завершает запрос, он возвращает только что запрошенный курсор к LoaderManager, который затем передает курсор методу onLoadFinished. Из документации "метод onLoadFinished вызывается, когда ранее созданный загрузчик завершил загрузку".

  • Запрошенные данные связаны с CursorAdapter.

    mAdapter.swapCursor(data);
    

    Обратите внимание, что onLoadFinished также обычно используется, когда вы обновляете пользовательский интерфейс активности/фрагмента с запрошенными данными. В этом случае это не обязательно, так как мы ранее называли setListAdapter(mAdapter). ListFragment знает, как использовать CursorAdapter (см. Шаг 1)... все, что нам нужно сделать, это передать адаптеру курсор с помощью swapCursor, а ListFragment позаботится о отображении данных на экран для нас.

Сообщите мне, есть ли у вас какие-либо вопросы (или если есть опечатки и т.д.).


TL; DR

Курсор, содержащий ваши запрошенные данные, связан с CursorAdapter in onLoadFinished. Обычно это делается путем вызова mAdapter.swapCursor(data).