getSupportLoaderManager() use same ids in different fragments?


Ask by : danielz March 04, 2013 15:59

I am making a viewPager in a FragmentActivity with multiple ListFragments. In order to populate the different listviews i get the LoaderManager and initiliaze in the loader. I wanted to have a unique LoaderManager for each fragment, however, fragments don't have a getSupportLoaderManager() method so i need to call the parent fragment activity:

getActivity().getSupportLoaderManager()

The problem with this approach that my Loaders id in different fragments conflicts with each others. It can get a little cumbersome when you already have multiple loaders id in one fragment. So is there a way to get an unique LoaderManager for each fragment, instead of calling the parent one? I basically want to be able to use the same id on multiple fragments.

Thank you

View original question

Answer by : SnicolasNovember 05, 2012 06:55

It would be too long a comment, but I continu our discussion within the comments of your question.

You should take it the other way around : live with the fact that the IDs are local to an activity, not to a fragment.

Yes, there is poor coupling between fragments and activities. Mostly call backs from fragments link the fragment to an activity (even when using an interface it's not that clean), and for passing arguments from an activity to a fragment : you must use a static factory method to both build the fragment and set its arguments via setArgs.

And your question is all about such a coupling issue : loaders IDs in each fragment of an activity should not overlap over the IDs used by all other fragments. That's a coupling constraint as well, as we have a constraint for fragment that lies at the activity level. You are right, that could maybe have been solved by Android at the fragment level by introducing loaders local to fragments.

Nevertheless, there might be elegant ways to solve that and preserve a relative de-coupling scheme. For instance, you could create a factory of IDs that would generate "good" IDs for loaders inside fragments and prevent overlapping (id++ would be perfect) :

public interface IdFactory {
   public int createId();
}

then inside each fragment, when you need a loader :

this.newLoaderId = idFactory.createId();

The factory could be shared by all fragments using one of the three strategies :

  • a singleton. Each fragment will access the IdFactory via

    IdFactory idFactory = DefaultIdFactory.getInstance();

  • create a single instance of a class that implements IdFactory, make that instance of that class a data field in your application class an give it a getter. Each fragment will be able to access it using

    IdFactory idFactory = ((MyApplication)getActivity().getApplicationContext() ).getIdFactory();

  • create your factories at the activity level. Either activities can implement the IdFactory interface or they can supply an inner class to do it. Each fragment would then access the factory using :

    IdFactory idFactory = getActivity().getIdFactory(); //or IdFactory idFactory = (IdFactory)getActivity();

The third option is the better as it will follow your exact need and will follow activities life cycles, allowing your factories to be garbage collected.

There are other options like using RoboGuice or Dagger or any other Dependency injection framework, but that is less standard.

View original answer