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 () . Я сподіваюся, що це поверне ідентифікатор, який ви пов’язали з завантажувачем.


Спасибі, Куртіс! Класно! Я спробую, але сподіваюся, що це спрацює. Я мав таку ж ідею, але не дивився на об’єкт навантажувача. Замість цього подивилися на об’єкт курсору ...
Kay Gladen

Він працює з Loader.getID ()! Я зараз двічі перевірив це. Чудово!
Кей Гладен

2
Я думаю зробити це за допомогою внутрішніх / анонімних класів, так що у кожного завантажувача є власний об'єкт отримання зворотних дзвінків.
Джордс

@KurtisNusbaum, чому це було б неправильно? Внутрішній клас буде знищений разом із зовнішньою Діяльністю, тому це не повинно спричинити витоку пам'яті чи нічого. Статичний клас із чітким посиланням на Діяльність семантично еквівалентний внутрішньому класу (який зберігає неявну чітку посилання на зовнішній клас.)
Маттіас

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;
    }
}    

8

Якщо ваші навантажувачі не мають нічого спільного, крім типу результату класу (тут Cursor:), вам краще створити два окремі LoaderCallbacksекземпляри (просто як два внутрішні класи у вашій діяльності / фрагменті), кожен з яких присвячений одній обробці завантажувача, а не ніж намагатися змішати яблука з апельсинами.

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


У мене одне питання. Метою Activityреалізації LoaderCallbacksта переходу thisдо цього getLoaderManager().initLoader()є забезпечення LoaderManagerфункціонування каналу комунікації між Activityта Loaderчерез LoaderCallbacks. Як тут створюється канал зв'язку, який Activityне реалізує, LoaderCallbacksа створює анонімні внутрішні класи?
AnV

3
Канал зв'язку - це LoaderCallbacks. Ніщо не вимагає використання самого Activityсебе як LoaderCallbacks. Простіше створити кілька каналів зв'язку, коли вони вам потрібні.
BladeCoder
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.