Global Loader (LoaderManager) for reuse in multiple Activities / Fragments

android, android-3.0-honeycomb, android-fragmentactivity, android-fragments, android-loadermanager

Solution

How to re-connect to the same Loader from a different Activity/Fragment than the one it was started in?

You should not reuse `Loader`s that are being managed by a `LoaderManager` instance across multiple `Activity`s and `Fragment`s.

The `LoaderManager` will start/stop those `Loader`s with respect to the `Activity`/`Fragment` lifecycle, so there is no way of guaranteeing that those `Loader`s will exist once you are in another `Activity`.

From the documentation:

LoaderManager.LoaderCallbacks is a callback interface that lets a client interact with the LoaderManager.

Loaders, in particular CursorLoader, are expected to retain their data after being stopped. This allows applications to keep their data across the activity or fragment's onStop() and onStart() methods, so that when users return to an application, they don't have to wait for the data to reload. You use the LoaderManager.LoaderCallbacks methods when to know when to create a new loader, and to tell the application when it is time to stop using a loader's data.

In other words, it is often the case that your `Loader`s will be specific to some Activity (or Fragment). When you have your `Activity` implement the `LoaderManager.LoaderCallbacks` interface, your Activity is given type `LoaderManager.LoaderCallbacks`. Each time you call `initLoader(int ID, Bundle args, LoaderCallbacks<D> callback)`, the LoaderManager either creates or reuses a `Loader` that is specific to some instance of the `LoaderManager.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 and `Fragment`s are both supposed to be designed for reuse, sharing `Loader`s in this way just doesn't seem like something that would be encouraged.

Problem

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.

Original source