Android Fragment - Using activity's loadermanager instead of Fragment's. Is it Ok?
Asked Answered
S

2

7

Given a fragment which loads (a lot of) data from the database using a loader.

Problem :

I have a pager adapter which destroys the fragment when the user moves away from the tab holding it and recreates it when user gets back to that tab. Because of this recreation, a new loader is created everytime and the data gets loaded everytime.

Question :

To avoid recreating loader everytime the fragment is created, is it ok to use getActivity.getSupportLoaderManager.initLoader(loaderId, null, false) in the onActivityCreated method of the fragment?

I have tried it, tested it and it seems to be working fine. But I'm not convinced that it is right.

Saretta answered 12/12, 2013 at 20:3 Comment(3)
I can't see a problem with this approach. Make sure that you use unique IDs per fragment (unless you're ok with reusing the same loader)Saulsauls
I have made sure the id is unique. It doesn't feel right. Because when the loader is created, the fragment registers itself as a callback and what if the system has destroyed the fragment, loader reloads the data and tries to call the onLoadFinished() method?Saretta
onLoadFinished would be called in the Activity, which would have to lookup the fragment. It could be there or not (in this case, just ignore the result). Anyway, I left a proper answer now.Saulsauls
S
2

Actually, checking the source code, you end up doing the same.

Fragment.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 is basically the fragment ID.

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

The difference in Activity.getLoaderManager() is that who will be (root)

So even though you can do what you are asking, calling it directly from the Fragment might be a better approach

Disclaimer: I only checked the source code in the latest version, but I don't expect it to be very different

Saulsauls answered 14/12, 2013 at 21:0 Comment(0)
P
0

May i ask why you are simply not retaining the Fragment? It seems that what you need is to create the Loader in the Fragment and create the fragment with setRetainInstance(true). In this case remember to provide a TAG when you add the fragment. This way the fragment will survive even to activity config changes and only the view will be recreated leaving your loader alive.

Paff answered 20/12, 2013 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.