What I would like to achieve:
I have two different fragments. I would like them both to show the same data in two forms (in a list and on a map). I would like them to share one Loader (AsyncTaskLoader
in particular). Everything works fine, but the Loader isn't re-used. Another one is created and the data is loaded twice.
What I do:
In the Fragment
s I use LoaderManager lm = getActivity().getSupportLoaderManager();
In both of them I implement LoaderCallbacks<ArrayList<Item>>
and the required methods.
In both I use lm.initLoader(0, args, this);
.
But when I output the lm.toString()
it appears that these are two different Loaders. And the data is downloaded twice.
How to re-connect to the same Loader from a different Activity/Fragment than the one it was started in?
It should be possible since the context is attached to the Loader anyway on every onCreate()
, e.g. on configuration change.
Yes. It worked for me. I have 3 different Fragments in a Navigation Drawer where the same data is populated in different ListViews. (All Fragments are a part of the SAME Activity).
My AsyncTaskLoader:
Use the Same Loader Id in all Fragments.
Fragment1:
Use the same Id for Fragment2:
The adapter should be initialized before initializing the loader. Works so far. But, is this the right way? Is there a better method for using a common loader for multiple Fragments?
You should not reuse
Loader
s that are being managed by aLoaderManager
instance across multipleActivity
s andFragment
s.The
LoaderManager
will start/stop thoseLoader
s with respect to theActivity
/Fragment
lifecycle, so there is no way of guaranteeing that thoseLoader
s will exist once you are in anotherActivity
.From the documentation:
In other words, it is often the case that your
Loader
s will be specific to some Activity (or Fragment). When you have yourActivity
implement theLoaderManager.LoaderCallbacks
interface, your Activity is given typeLoaderManager.LoaderCallbacks
. Each time you callinitLoader(int ID, Bundle args, LoaderCallbacks<D> callback)
, the LoaderManager either creates or reuses aLoader
that is specific to some instance of theLoaderManager.LoaderCallbacks
interface (which in this case is an instance of your Activity). This essentially binds your Activity with a Loader, and its callback methods will be called as the loader state changes.That being said, unless you can find a way to have your two separate Activitys share the same callback methods, I doubt there is a clean way to do this (i.e. having an Activity and a Fragment share the same callbacks sounds like it would be tricky, if not impossible). I wouldn't worry about it too much though. In all of the sample code I have ever seen, I've never seen two Activitys and/or Fragments share the same callback methods. Further, given that
Activity
s andFragment
s are both supposed to be designed for reuse, sharingLoader
s in this way just doesn't seem like something that would be encouraged.I think you'll have the desired behavior if you use the same Loader ID across your different Fragments and Activities. Make sure the loader ID are unique to the data to load though. PhotosLoader and VideoLoader shouldn't have the same id for example.
I'm not quite sure what you're trying to archieve after going through the discussions. But there is an
application.registerActivityLifecycleCallbacks()
method, which accept global activity lifecycle listeners (likeonActivityCreated()
).