LoaderCallbacks.onLoadFinished () никогда не вызывается с FragmentPager?

1

Я использую FragmentPagerAdapter для реализации интерфейса с вкладками. Мой 0-й фрагмент создает загрузчик во время создания и пытается повторно подключиться к загрузчику в onActivityCreated(). Здесь класс:

public class My0thFragment extends Fragment {
    private boolean ranOnce = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true); 
    }

    @Override
    public void onActivityCreated() {
        if (!ranOnce) {
            // if the first time we're being created, do an initial load of data.
            getLoaderManager().initLoader(500, null, mMyCallback).forceLoad();
            ranOnce = true;
        } else {
            // reconnect?
            getLoaderManager().initLoader(500, null, mMyCallback);

            // sanity check.
            printAllLoaders(getLoaderManager());
        }
    }

    private LoaderManager.LoaderCallbacks<Foo> mMyCallback = new LoaderManager.LoaderCallbacks<Foo>() {
        @Override
        public Loader<Foo> onCreateLoader(int arg0, Bundle arg1) {
            return new FooLoader(getActivity(), arg1);
        }

        @Override
        public void onLoadFinished(Loader<Foo> arg0, Foo arg1) {
            Log.e(tag, "onLoadFinished()!");
        }

        @Override
        public void onLoaderReset(Loader<Foo> arg0) {
            Log.e(tag, "onLoaderReset()!");
        }
    };
}

И вот сценарий:

  1. App запускает, 0-й фрагмент создается в FragmentPagerAdapter.
  2. Вызывается метод onActivityCreated(), который создает и запускает загрузчик при первом запуске.
  3. Я быстро переключаюсь на другую вкладку, пока загрузчик еще не завершил работу.
  4. Я вижу через журналы, что загрузчик заканчивается, но мой callback никогда не получает обратный вызов onLoadFinished(). Я предполагаю, что это происходит потому, что фрагмент находится в каком-то отдельном состоянии, в зависимости от того, как работает FragmentPagerAdapter.
  5. Возвращаясь к 0-й вкладке, я вижу, что onActivityCreated() вызывается, а метод initLoader() вызывается снова. Обратный вызов все еще не срабатывает.
  6. Я могу напечатать все загрузчики в менеджере загрузчика на этом этапе и увидеть, что мой загрузчик все еще сидит в менеджере загрузчика.

Поэтому я застрял здесь, я должен делать что-то неправильно, так как материал Loader должен был быть разработан для удобства использования разработчиками с учетом жизненных циклов фрагментов. Может ли кто-нибудь указать, что я здесь делаю неправильно?

спасибо

Теги:

3 ответа

6

Вероятно, у вас есть два экземпляра одного и того же фрагмента, попробуйте уничтожить загрузчик при уничтожении фрагмента:

protected void onDestroy() {
   if (getSupportLoaderManager().getLoader(0) != null) {
            getLoaderManager().getLoader(0).abandon();
            getSupportLoaderManager().destroyLoader(0);
    }
    super.onDestroy();
}
2

Не знаете, решили ли вы свою проблему или нет, но вы должны вызвать forceLoad() на Fragment.onStart() вместо Fragment.onActivityCreated().

MyCallback.onLoadFinished() никогда не вызывается, потому что ваш "myCallback" на самом деле не привязан к загрузчику до тех пор, пока ваш фрагмент не будет запущен.

0

См. Пример файла кода FragmentTabsPager.java из API Demos или Support4Demos. Он предоставляет ViewPager и TabHost, которые управляют одним и тем же набором фрагментов. Я взломал его, чтобы охватить именно тот случай, который вы описали. (Вы обращались ко мне напрямую?) Главное отметить, что пример приложения не отделяет фрагменты в ViewPager.

Здесь часть, где я ее взломал:

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTabHost = (TabHost)findViewById(android.R.id.tabhost);
    mTabHost.setup();

    mViewPager = (ViewPager)findViewById(R.id.pager);

    mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);

    mTabsAdapter.addTab(mTabHost.newTabSpec("fraga").setIndicator("Fragment A"),
            FragmentA.class, null);
    mTabsAdapter.addTab(mTabHost.newTabSpec("fragb").setIndicator("Fragment B"),
            FragmentB.class, null);

    if (savedInstanceState != null) {
        mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
    }

}

Фрагмент A - это тот, который содержит Loader.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню