Inter-Fragment Communication

This is the third part of a 6 posts series on Fragment oriented application architecture. In the previous post I talked about Transaction BackStack and its management. In this part I am going to talk about Inter-Fragment Communication. It’s a general concept, not deeply linked to the context of this series.

(Sample application’s source code and README)

It’s a communication pattern over which fragments should talk to each other. Ideally, a fragment should never keep a reference of another fragment or even, in best case, of the specific parent activity. So, how would two fragments communicate? Consider the following scene.

fragments1

Selecting an item in Fragment A needs to update UI of Fragment B by sending a message. You would probably get tempted to keep a reference to Fragment B inside Fragment A. Easy way out! But doing so would lead to tight coupling between these two fragments. That ruins the most basic purpose of fragments, i.e., reusability.

To do this communication we can use an interface that is implemented in activity and it’s reference is kept in Fragment A. Following diagram illustrates the communication pattern.

interface

TheActivity implements Communicator interface which requires to override a method that, in turn, calls a method on Fragment B which does the required change in UI of Fragment B. Fragment A can keep a reference to a ‘Communicator’ instance and delegate the task to implementer of the interface. Fragment A might enforce the host Activity to implement Communicator as follows

// ENFORCING IMPLEMENTATION OF INTERFACE

if(!(getActivity() instanceof Communicator)) {
   throw new ClassCastException("Host activity must implement Communicator interface");
} else {
   communicator = (Communicator) getActivity();
}

Sample application has a section on ‘Inter-fragment communication’. In First fragment of this section, enter your name and press ‘See Greetings’ button, app then navigates to next fragment (a replace transaction) where it greets you using your name. So, the name you entered in first fragment has to be sent to second fragment.

Activity implements an interface (GreetingsInterface) which exposes a method to spawn an instance of GreetingsFragment that would show greetings. First fragment would keep an instance of this interface and would call showGreetings(name) method on it. At this point, first fragment has delegated the task to implementer of interface i.e., Home activity in this case. Now it’s up to Home how it handles it.

This communication pattern has been employed throughout the sample app. Check out its other use cases in the code.

Another clean and useful pattern has been involved here, of keeping a static instance(params) method in a fragment class which returns an instance of it with a Bundle of params as arguments.

// STATIC INSTANCE METHOD

public static GreetingsFragment instance(String name) {
    Bundle arguments = new Bundle();
    arguments.putString(EXTRA_NAME, name);
    GreetingsFragment greetingsFragment = new GreetingsFragment();
    greetingsFragment.setArguments(arguments);
    return greetingsFragment;
}

P.S.: Although this is the standard communication pattern in java, in a vast application the number of interfaces might grow huge, resulting into an excessive amount of boiler-plate code. An alternative to this is the concept of EventBus. Check out Otto and Green robot’s EventBus.

In the next post I’m going to talk about Efficiently handling back-press in Fragments.

6 thoughts on “Inter-Fragment Communication

  1. Hi,
    thanks for your great posts, they are very clear.

    As you mentionned, the also EventBus is a good pattern to use.
    Actually, I would like to underscore that using the EventBus is very clean.
    You can use the EventBus for most inter-fragments communication but also Service to fragments, Broadcast to fragments, web service result to fragment, db to fragment, etc.
    And sometimes, even vice-versa.

    Keep in mind that a fragment should not know about other fragments.

  2. Thanks a lot. Is it possible to elaborate on the merits/demerits of having an explicit EventBus (as in Otto & Greenrobot’s versions). Again, thanks a lot.

  3. Yes, elaboration is very much possible. I’m planning to write a post on EventBus soon.

  4. Yes, indeed. EventBus does the pure decoupling of components. GreenRobot’s EventBus is the best among EventBus implementations for Android I’ve seen so far.

  5. Excellent article! Just one question:

    “Fragment A can keep a reference to a ‘Communicator’ instance and delegate the task to implementer of the interface.”
    If you keep this references, it’s not the same as to keep the Activity reference?
    Sorry for the basic question but I would like to understand this as I was always concerned about memory leaks.

    Thanks in advance!

  6. The use of Interface here is not dealing with memory leaks. Handling memory leaks is a different world. Interface here is saving a piece of code from tight coupling. Although we are passing reference of an Activity that implements Communicator, the Fragment that uses this communicator interface doesn’t need to know which specific class is implementing it. In other words, FragmentA has no idea about the existence of TheActivity. If you want to dig deeper into this, please check out my other blog post here http://vinsol.com/blog/2014/11/04/communication-patterns-for-application-components/

Leave a Reply

Your email address will not be published. Required fields are marked *