Фрагмент Android — использование диспетчера загрузки активности вместо фрагмента. Это нормально?

Дан фрагмент, который загружает (много) данных из базы данных с помощью загрузчика.

Проблема:

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

Вопрос:

Чтобы избежать повторного создания загрузчика каждый раз, когда создается фрагмент, можно ли использовать getActivity.getSupportLoaderManager.initLoader(loaderId, null, false) в методе onActivityCreated фрагмента?

Я пробовал, тестировал, вроде работает нормально. Но я не уверен, что это правильно.


person 500865    schedule 12.12.2013    source источник
comment
Я не вижу проблемы в таком подходе. Убедитесь, что вы используете уникальные идентификаторы для каждого фрагмента (если вы не согласны с повторным использованием одного и того же загрузчика)   -  person Pedro Loureiro    schedule 15.12.2013
comment
Я убедился, что идентификатор уникален. Это неправильно. Потому что при создании загрузчика фрагмент регистрируется как обратный вызов, а что, если система уничтожила фрагмент, загрузчик перезагружает данные и пытается вызвать метод onLoadFinished()?   -  person 500865    schedule 15.12.2013
comment
onLoadFinished будет вызываться в действии, которое должно будет искать фрагмент. Он может быть там или нет (в этом случае просто игнорируйте результат). Во всяком случае, я оставил правильный ответ сейчас.   -  person Pedro Loureiro    schedule 15.12.2013


Ответы (2)


На самом деле, проверяя исходный код, вы делаете то же самое.

Фрагмент.getLoaderManager:

/**
 * Return the LoaderManager for this fragment, creating it if needed.
 */
public LoaderManager getLoaderManager() {
    if (mLoaderManager != null) {
        return mLoaderManager;
    }
    if (mActivity == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to Activity");
    }


    mCheckedForLoaderManager = true;
    mLoaderManager = mActivity.getLoaderManager(mWho, mLoadersStarted, true);
    return mLoaderManager;
}

mWho в основном является идентификатором фрагмента.

final void setIndex(int index, Fragment parent) {
    mIndex = index;
    if (parent != null) {
        mWho = parent.mWho + ":" + mIndex;
    } else {
        mWho = "android:fragment:" + mIndex;
    }
}

Разница в Activity.getLoaderManager() в том, кто будет (root)

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

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

person Pedro Loureiro    schedule 14.12.2013

Могу я спросить, почему вы просто не сохраняете Фрагмент? Кажется, вам нужно создать загрузчик во фрагменте и создать фрагмент с помощью setRetainInstance(true). В этом случае не забудьте указать TAG при добавлении фрагмента. Таким образом, фрагмент сохранится даже при изменении конфигурации активности, и будет воссоздано только представление, оставив ваш загрузчик живым.

person Pasquale Anatriello    schedule 20.12.2013