3

I am using CursorLoader to load data from database inside my Fragment, which has a RecyclerView. This fragment is being used inside a ViewPager. The ViewPager is contained inside a ContainerFragment, which in turn is inside an Activity.

The ContainerFragment initializes first 4 loaders out of the 10 required in onActivityCreated(). From the log I can see that the loader(s) are in fact getting created. However, onLoadFinished is not getting called for any of the loaders.

Now the twist comes when I swipe through the ViewPager to the third fragment. Now I see the third loader's onLoadFinished getting called. Now this is probably not called from the fragment but from the PagerAdapter's getItem() method, which in addition to instantiating the fragments, also initializes loaders with their IDs in case they haven't been already.

From all other questions on StackOverflow about onLoadFinished not getting called, I have tried the following solutions which are not working for me:

  1. Using forceLoad()
  2. this.getListView().refreshDrawableState(); -> not tried, and don't understand why this should work. Moreover, I am using RecyclerView.
  3. "Importing the correct class" -> I am using AndroidX, and moreover, the loader does load sometimes. If it was the wrong class, it wouldn't have worked any time right?
  4. "Fragment should use SupportLoaderManager" -> tried replacing in the fragment with getActivity().getSupportLoaderManager. For fragment I think it's just getLoaderManager. It was already working sometimes with just getLoaderManager. (No difference observed)

#onActivityCreated

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    startLoaders();
}

startLoaders()

private void startLoaders() {
    while(loaderSeqIndex < CATEGORIES.size() && loaderSeqIndex < 4) {
        Bundle bundle = new Bundle();
        bundle.putString("category", CATEGORIES.get(loaderSeqIndex));
        getLoaderManager().initLoader(loaderSeqIndex++, bundle, this);
    }
}

LoaderCallbacks

@NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
    Timber.i("Loader created onCreateLoader called");
    CursorLoader loader = ArticleLoader.newCategorizedArticlesInstance(getContext(), args.getString("category"));
    loader.registerListener(id, new Loader.OnLoadCompleteListener<Cursor>() {
        @Override
        public void onLoadComplete(Loader<Cursor> loader, Cursor data) {
            int position = loader.getId();
            cursorHashMap.put(CATEGORIES.get(position), data);
            Timber.i("mPager.getCurrentItem(): " + mPager.getCurrentItem() + " position: " + position);
            if (position == mPager.getCurrentItem()) {
                ArticleListViewModel model = ViewModelProviders.of(ArticleListContainerFragment.this).get(ArticleListViewModel.class);
                model.setCursor(data);
            }
        }
    });
    return loader;
}

@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
    int position = loader.getId();
    cursorHashMap.put(CATEGORIES.get(position), data);
    Timber.i("mPager.getCurrentItem(): " + mPager.getCurrentItem() + " position: " + position);
    if(position == mPager.getCurrentItem()) {
        ArticleListViewModel model = ViewModelProviders.of(this).get(ArticleListViewModel.class);
        model.setCursor(data);
//            mPagerAdapter.notifyDataSetChanged();
    }
}

PagerAdapter's #getView

private class MyPagerAdapter extends FragmentStatePagerAdapter {
...
     @Override
     public Fragment getItem(int position) {
        ArticleListFragment fragment = ArticleListFragment.newInstance();
        Bundle bundle = new Bundle();
        bundle.putString("category", CATEGORIES.get(position));
        bundle.putInt("id",position);
        fragment.setArguments(bundle);
//            fragment.setCursor(cursorHashMap.get(CATEGORIES.get(position)));
        return fragment;
    }
...
}

I was expecting timber to print from the #onLoadFinished method just to make sure that it's getting called, which isn't happening.

Something weird that is happening is that: the cursorHashMap that I am using, get's properly populated I open the app a second time (when refresh doesn't happen). And the cursor get's populated without #onLoadFinished being called.

0 Answers0