LoaderManager с несколькими загрузчиками: как получить правильный загрузчик курсора

116

Мне непонятно, как получить правый курсор, если у вас несколько загрузчиков. Допустим, вы определяете два разных загрузчика с помощью:

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

затем в onCreateLoader () вы делаете разные вещи в зависимости от идентификатора:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {

    if (id==0){
               CursorLoader loader = new CursorLoader(getActivity(),
            MaterialContentProvider.CONTENT_URI,null,null,null,null);
    }else{
               CursorLoader loader = new CursorLoader(getActivity(),
            CustomerContentProvider.CONTENT_URI,null,null,null,null);
            };
    return loader;
} 

Все идет нормально. Но как получить правый курсор в onLoadFinished (), потому что у вас нет идентификатора для определения правильного курсора для правильного Cursoradapter.

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {


    mycursoradapter1.swapCursor(cursor);
    if(isResumed()){
        setListShown(true);
    }else {
        setListShownNoAnimation(true);
    }



}
//and where to get the cursor for mycursoradapter2

или я ошибаюсь и это неправильный способ получить результаты для двух разных курсоров в одном фрагменте.

Кей Глэйден
источник
Это действительно хороший вопрос! Это хорошо заданный вопрос, и он затрагивает довольно тонкую тему. Очень специфично.
Куртис Нусбаум,
7
Следует отметить, что вы должны использовать отдельные классы обработчиков, когда тип возврата загрузчика не является одинаковым для всех загрузчиков, поскольку из-за стирания общего типа Java не позволяет вам реализовать интерфейс ( LoaderCallbacksв данном случае) с более чем одним тип. Это просто работает в вашем случае, так как в обоих случаях результат будет Cursor.
Маттиас
1
@Matthias Отлично, ты упомянул об этом! Я просто обдумываю, как иметь 2 загрузчика с разным типом возврата. Так что, если 2 загрузчика с 2 разными типами возврата? Выполнять одну задачу с 1 загрузчиком, а другую - с потоком?
Роберт
@Robert Не нужно использовать нить. Вы можете использовать два Loaders. Пожалуйста, просмотрите этот stackoverflow.com/a/20839825/2818583
AnV

Ответы:

119

В классе Loader есть метод getId () . Я надеюсь, что это вернет идентификатор, который вы связали с загрузчиком.

Куртис Нусбаум
источник
Спасибо, Куртис! Прохладно! Я попробую, но ожидаю, что это сработает. У меня была такая же идея, но я не смотрел на объект загрузчика. Вместо этого взглянули на объект курсора ...
Кей Глэйден
Работает с Loader.getID ()! Я перепроверил это прямо сейчас. Большой!
Кей Глэйден,
2
Я подумываю сделать это с помощью внутренних / анонимных классов, чтобы у каждого загрузчика был собственный объект, получающий обратные вызовы.
Йорды
@KurtisNusbaum, почему это неправильно? Внутренний класс будет уничтожен вместе с внешним Activity, поэтому это не должно привести к утечке памяти или чему-то еще. Статический класс со строгой ссылкой на Activity семантически эквивалентен внутреннему классу (который сохраняет неявную сильную ссылку на внешний класс.)
Маттиас
6
@Jords Это технически правильно. Я не спорю об этом. Но зачем делать все это, если можно просто позвонить getId()?
Куртис Нусбаум
32

Используйте метод загрузчика getId () :

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    switch (loader.getId()) {
        case 0:
            // do some stuff here
            break;
        case 1:
            // do some other stuff here
            break;
        case 2:
            // do some more stuff here
            break;
        default:
            break;
    }
}    
IgorGanapolsky
источник
8

Если у ваших загрузчиков нет ничего общего, кроме типа класса результата (здесь :) Cursor, вам лучше создать два отдельныхLoaderCallbacks экземпляра (просто как два внутренних класса в вашем Activity / Fragment), каждый из которых предназначен для обработки одного загрузчика, а чем пытаться смешивать яблоки с апельсинами.

В вашем случае кажется, что и источник данных, и обработка результатов различаются, что требует от вас написать дополнительный шаблонный код, чтобы идентифицировать текущий сценарий и отправить его в соответствующий блок кода.

BladeCoder
источник
У меня есть один вопрос. Целью Activityреализации LoaderCallbacksи переходя thisк getLoaderManager().initLoader()является обеспечение того , LoaderManagerвыступает в качестве канала связи между Activityи Loaderчерез LoaderCallbacks. Как этот канал связи создается здесь, поскольку Activityон не реализует, LoaderCallbacksа создает анонимные внутренние классы?
AnV
3
Канал связи - это LoaderCallbacks. Ничто не требует использования Activityсамого как LoaderCallbacks. Когда вам нужно, проще создать несколько каналов связи.
BladeCoder