Part 7: Simple Ways To Stab With Dagger 2 ( Life of a scoped object)

Santosh Dhakal
4 min readJun 6, 2017

--

This is continuation from Part 6, where we had discussed about Scopes and Singleton scope.

Before moving on to custom scope, we need to briefly understand the life of scoped object . Meaning when the scoped object will be garbage collected (GC’ed). Here we are dealing with singleton scope, but this concept is valid to custom scoped object as well.

In Java, the life of a variable inside a class instance in general case be alive as long as that class instance is alive and those variables are not referenced elsewhere. Meaning, that variable will not be GC’ed as long as the object holding/referencing it is alive. If some of you might be not clear on concepts of heap, memory, pass by value and stuff, please follow following blog posts

as these are very helpful in understanding the concepts of scopes.

While using @Singleton, the CoffeeHelper object is referenced from two locations

To be precise, it is referenced from

  • Restaurant A
  • Provider<CoffeeHelper> ( this in turn resides on CoffeeComponent class )

So, if two of the objects are alive i.e . RestaurantA instance and CoffeeComponent instance, then our CoffeeHelper object is also alive. Let us look upon the following code

@Inject
public CoffeeHelper coffeeHelper;
private CoffeeComponent coffeeComponent;
private void goDagger() {
coffeeComponent = DaggerCoffeeComponent.builder().build();
coffeeComponent.provideCoffee(this);
coffeeComponent = null;
}

Here after initializing the coffeeHelper , we are nullifying coffeeComponent.

Q) Does this mean that our coffeeHelper will be null now? Let us check this with memory profiler. ( Note: I have done Force Garbage Collection in memory profiler, so that coffeeComponent object can be GC’ed)

Here CoffeeHelper is now referenced from Restaurant A only. This does not mean that you have to set coffeeHelper = null on Restaurant A onDestroy() method. Meaning if Restaurant A is no more, coffeeHelper will also be GC’ed (as we have already nullified our component) .Once the fragment is cleared up by Android, we need not be concerned of the local variables ( if they are not referenced by any other objects ). What I am trying to point out is that, the life of a scoped object is mainly dependent on component itself. As long as the component is alive, so are the scoped objects. Let me illustrate this with following changes in our code.

Hotel A now initializes our component

public CoffeeComponent getCoffeeComponent() {
if (coffeeComponent == null)
coffeeComponent = DaggerCoffeeComponent.builder().build();
return coffeeComponent;
}

public void clearComponent() {
coffeeComponent = null;
}

And the fragment ( Restaurant A) simply takes the component from Hotel A

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getContext() instanceof HotelA) {
hotelA = (HotelA) getContext();
}
}
@Inject
public CoffeeHelper coffeeHelper;
private void withDagger() {
if (hotelA != null) {
hotelA.getCoffeeComponent().provideCoffee(this);
}
}

Here it is seen that CoffeeHelper instance is referenced from Restaurant A and DoubleCheck. Now let us switch our fragment to Restaurant B such that Restaurant A gets destroyed and see whether coffeeHelper instance is still alive in memory or not

We can see that the coffeeHelper instance is still alive in memory as coffeeComponent is still alive in Hotel A. And if we simply do the following changes on Restaurant A and Hotel A

//Restaurant A
@Override
public void onDestroy() {
if (hotelA != null) {
hotelA.clearComponent();
}
super.onDestroy();
}
//Hotel A
public void clearComponent() {
coffeeComponent = null;
}

We are simply nullifying the component on onDestroy() of the fragment and when we see the memory profiler again, we won’t see any instance of coffeeHelper ( when navigating from Restaurant A to Restaurant B) present as it is no longer referenced from component.

This shows that the life of a scope object lives as long the component is alive (at Hotel A) and as long as the object ( Restaurant A) in which it is injected. Since the objects inside a fragment, activity is handled by Android itself, it is duty of the developer to clear out the component, if they don’t want the injected object to live in the memory. This concept is same for the custom scoped objects as well. All the code related to this blog post can be found here https://github.com/androidlife/get-a-fix-of-dependency/tree/life_of_singleton.

In the final series , I am going to talk about the custom scopes that can be used with Dagger 2.

--

--

Santosh Dhakal

Android app developer having a deep interest in mobile technology be it Android or iOS. Loves to learn ,share the knowledge and build things.