Sahil Goel

Exploring the new Android Architecture Components (Part 1)

At Google I/O 2017, Google introduced new architecture components for Android. It is a new library which will help developers to maintain their activities or fragments lifecycle very easily.

This new library by Google provides some relief to the Android Developers by providing a complete solution to problems like memory leaks, data persistence during configuration changes and also helps in reducing some boilerplate code.

architecture components(android)

There are 4 Android Architecture Components :

  1. Lifecycle
  2. LiveData
  3. ViewModel
  4. Room

Lifecycle

Lifecycle class helps us in building lifecycle aware components. It is a class which holds all the information about the states of an activity or a fragment. It allows other objects to observe lifecycle states like a resume, pause etc.

There are 2 main methods in the Lifecycle class:

  1. addObserver() – Using this method, we can add a new instance of a “LifecyleObserver” class which will be notified whenever our “LifecycleOwner” changes state. For example: if an activity or a fragment is in RESUMED state then our “LifecycleObserver” will receive the ON_RESUME event.
  2. removeObserver() – This method is used for removing active “LifecycleObserver” from the observer’s list.

LifecycleObserver

With the help of this interface, we can create our Observer class which will observe the states of an activity or a fragment. We need to simply implement this “LifecycleObserver” interface.

LifecycleOwner

It is an interface with a single method called “getLifecycle()”. This method must be implemented by all the classes which are implementing this interface. This interface denotes that this component (an activity or a fragment) has a lifecycle.

Now, let’s look at an example of how we can use the LifecycleObserver and LifecyclerOwner interfaces to manage the component lifecycle.

public class MyObserver implements LifecycleObserver {

    public MyObserver(Lifecycle lifecycle){
        lifecycle.addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume(){
        // Will be called "after" onResume method of the Lifecyle Owner class.
        // (MyActivity in this example)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy(){
        // Will be called "before" onDestroy method of the Lifecyle Owner class.
        // (MyActivity in this example)
    }
}

public class MyActivity extends AppCompatActivity implements
        LifecycleRegistryOwner{

    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // Now MyObserver class will observe all the events of this activity.
        new MyObserver(lifecycleRegistry);
    }

    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }
}

 

Any class whose states we want to listen must implement the “LifecycleRegistryOwner” interface. And any class who wants to listen must implement the “LifecycleObserver” interface.

There are several events which we can listen with the help of the “LifecycleObserver” interface:

  • ON_CREATE – Will be called after onCreate() method of the “LifecycleOwner”.
  • ON_START – Will be called after onStart() method of the “LifecycleOwner”.
  • ON_RESUME -Will be called after onResume() method of the “LifecycleOwner”.
  • ON_PAUSE – Will be triggered upon the “LifecycleOwner” being paused (before onPause() method).
  • ON_STOP – Will be triggered upon the “LifecycleOwner” being stopped (before onStop() method).
  • ON_DESTROY – Will be triggered by the “LifecycleOwner” being destroyed (before onDestroy() method).

 

LifecycleObserver interface

 

All these events are enough for managing the lifecycle of our views. With the help of these  “LifecycleObserver” and “LifecycleOwner” classes, there is no need to write methods like onResume(), onPause() etc in our activities or fragments. We can handle these methods in our observer class.

We can also get the current state of the “Lifecycle Owner” with the help of getCurrentState() method.

public class MyObserver implements LifecycleObserver {

    private Lifecycle lifecycle;
    public MyObserver(Lifecycle lifecycle){
        this.lifecycle = lifecycle;
        lifecycle.addObserver(this);
    }

    public void enable(){
        if(lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED)){
            // This will check if an activity is at least Started or not.
        }
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop(){
        // Will be called "before" onStop method of the Lifecyle Owner class.
        // (MyActivity in this example)
    }
}

LiveData

LiveData is a data holder class. It provides us the ability to hold a value and we can observe this value across lifecycle changes.

Yeah, you heard that right! 🙂

LiveData handles the lifecycle of app components automatically. We only need to observe this LiveData class in our components. That’s it and we are done. 🙂

There are some important methods of LiveData:-

  • onActive() – Called when there is an active observer. An observer is called active observer when its lifecycle state is either STARTED or RESUMED and the number of active observers changes from 0 to 1.
  • onInactive() – Called when there are no active observers. An observer is called inactive observer when its lifecycle state is neither STARTED nor RESUMED (like an activity in the back stack) and the number of active observers changes from 1 to 0.
  • setValue() – Used to dispatch the results to the active observers. This method must be called from the main thread.

Now let’s see an example where we can see how LiveData can be used for our LocationHelper class which sends the location updates to all classes which are observing our helper class.

public class LocationHelperLiveData extends LiveData<Location> implements LocationListener{

    private LocationManager mLocationManager;

    @Override
    protected void onActive() {
        super.onActive();
        // Here we can start requesting location updates and 
        // can create our GoogleApiClient for locations.
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        // Here we can stop requesting location updates.
    }

    @Override
    public void onLocationChanged(Location location) {
        setValue(location);
        // This method will post the location updates to the Observer.
        // (MyActivity in this example)
    }
}

 

Now we can use our LocationHelperLiveData:- 

public class MyActivity extends AppCompatActivity implements 
        LifecycleRegistryOwner{

    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new LocationHelperLiveData().observe(this, new Observer<Location>() {
            @Override
            public void onChanged(@Nullable Location location) {
                // Here we receive updated location value.
            }
        });
    }

    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }
}

 

In above example, we created one LocationHelperLiveData class which posts Location data to the MyActivity class, and it also manages the Lifecycle of MyActivity.

In above method observe() we pass the Lifecycle Owner as an argument, this argument denotes that LocationHelperLiveData class should be bound to the Lifecycle of the MyActivity class. This bounding relationship of helper class with our Activity denotes that:-

  • Even if the value changes, the observer will not be called if the Lifecycle is not in an active state (STARTED or RESUMED).
  • The observer will be removed automatically if the Lifecycle is destroyed.

Whenever MyActivity is in either PAUSE or STOP state it will not receive location data. It will start receiving Location Data again once MyActivity is in either RESUME or START state.

There can be multiple Activities or Fragments which can observe LocationHelperLiveData instance and our LiveData class will manage their Lifecycle automatically.

There is no need to remove observer in onDestroy() method, it will be removed automatically once LifecycleOwner is destroyed.


That’s all for now. I hope this blog helps you in setting up Lifecycle and LiveData Android components in your app. We’ll see how we can use LiveData with ViewModel in my next blog.

Thank you for reading.