From Fragments to Activity: the Lambda Way

Stephane NICOLAS
Sep 29, 2017 · 5 min read

have their lifecycle, and the same goes for. Hence, communication from to is notoriously problematic.

The communication between and cannot be as simple as passing a listener to the fragment that the activity could implement: the would soon rotate and the would keep a reference to an that had died and would leak. Google recommends a “good old pattern” to achieve this goal and limit the risk of leaks. In this article, we will demonstrate that lambdas are a better solution, more expressive, and easier to maintain.

We have created a Github repo that contains the code of our solution:

The Good Old Way

The official way to make a Fragment communicate with its hosting Activity involves creating a communication interface and to implement it in the :

MainActivity, the Good Old Way

The will get a reference to its hosting and use an ugly and risky cast to communicate to the via the communication interface:

HeadLinesFragment, the Good Old Way

There are various issues with this approach:

  1. the casting statement is ignominious and fails at runtime.
  2. you don’t see clearly how the and the are linked. The link is more implicit than explicit.

This makes the Good Old Way crash-prone, and hard to maintain. Let’s try something different!

The Lambda Way

The Lambda Way will favor composition over inheritance. We don’t want our class to implement the communication interface anymore:

MainActivity, The Lambda Way

Our communication interface is modified to use any . Thus it becomes independent of the instance and won’t leak it:

HeadlineListener, The Lambda Way

We will see below why it uses a generic and it is .

The will pass its current hosting instance to the listener when it wants to communicate with it:

HeadLinesFragment, The Lambda Way

And here’s he key: the activity will now set a listener to the , using a simple method reference.

Setting the listener, The Lambda Way

What is this method reference : ?

This is one of the tough questions of this approach, and it gives us an opportunity for a good dive into the Java syntax.

Actually, is an ambiguous java statement. It can represent:

  • either a reference to a static method;
  • OR a reference to non static method of object of a specific type.

If was a static method of , we could refer to it via . Referencing a static method is the most typical use of this type of reference.

But, in our case, is **not** static. So, we would usually refer to it as . This method reference would point to the non-static method . You could use, for instance, in a Rx chain to map an observable of positions:`

Using the normal method reference this::onArticleSelected in a Rx Chain.

So, what does refer to ??

Internally, all non-static methods in Java are compiled in the same way as static methods, but with one hidden first parameter of the type of its enclosing class. Thus, the 2 methods below are almost equal from the byte code perspective:

Non-Static methods have a hidden first parameter of the type of the enclosing class.

The method reference is a reference to the second form of this method. It is now pointing to a method that takes 2 parameters: a and a .

This second method is interesting for us because it is independent of the instance. Hence, a reference to it doesn’t leak the activity instance!

From a lambda perspective, the meaning of this method reference is now slightly different: it is indeed a method that accepts a and invokes the method on this activity:

is equivalent to

In other words, is a method reference to a implementation that is independent of the activity and will work with any instance of .

For a fine-grained explanation of method references, please visit the official Java documentation.

Disambiguating MainActivity::onArticleSelected

As explained above, this method reference can be misunderstood by the Java compiler. It could understand it as a static method reference. In order to disambiguate it, both the interface , and the method will use generics to trigger what is called a target type inference:

HeadlineListener, The Lambda Way. The generic trigger a target type inference.
Setter method. The generic trigger a target type inference.

Thanks to these 2 generics, the compiler understands that the future method reference passed to as a reference to a non static method of object of a specific type, and it will only accept references that point to a method inside a class that extends . This last constraint is reasonable because, from a perspective, we can easily get the hosting Activity using . This is why we can now invoke our listener method on the current :

Surviving the Fragment Lifecycle

The last point is to make sure that our fragment still knows about its callback when it dies and it is recreated by the (e.g. after a rotation). For this, we will serialize the listener into the arguments of the fragments.

In our Github repo, we opted for a very structured approach to create our by using a builder pattern. The builder will let you create the fragment with an appropriate listener. Of course, the builder is not mandatory for the “lambda way” to work, you just need to serialize the lambda and you can do it the way you want.

It is generally advised not to serialize lambdas in Java, exactly for the same reasons as inner classes. Nevertheless, this issue is softened here as:

  • on Android, serialization is short term and cannot create issues during application upgrades and class changes.
  • the lambda/method reference is fully static and stateless, and is intrinsically protected from any serialization issue as it can’t contain any reference to a non serializable element nor refer to entities that could have died (e.g. the or the ).


This new approach is quite technical, we agree on this. It also infringes the general rule of not serializing lambdas. However, we believe that this approach brings a few benefits to our code base:

  • The link between Activities and Fragments is now explicit. It can be traced easily inside our IDE as opposed to implementing an interface the Good Old Way.
  • We got rid of the hideous casting of the Good Old Way.
  • We favor composition over inheritance.
  • Code looks quite close to the rest of our modern Rx chains.
  • When using a with such an API, using the listener interface is as easy as using a method reference and most of the complexity of the solution goes behind the scene.
  • It enforces building fragments using a builder pattern to setup the arguments which reduces bugs at runtime.

Thanks to Samuel Guirado Navarro for bullet proofing the approach.

Let us know what you think, and thx for reading this article !
With 💚 , the Groupon Android team.

Groupon Engineering

Tech blog from Groupon Engineers

Thanks to Carlos Sessa, Mihaly Nagy, Alin Turcu, Cody Henthorne, daniel hw, Eric Farraro, and Samuel Guirado Navarro.

Stephane NICOLAS

Written by

Groupon Engineering

Tech blog from Groupon Engineers