An Android Lifecycle Awareness Tutorial

The previous chapter provided an overview of lifecycle awareness and outlined the key classes and interfaces that make this possible within an Android app project. This chapter will build on this knowledge base by building an Android Studio project to highlight lifecycle awareness in action.

Creating the Example Lifecycle Project

Select the New Project quick start option from the welcome screen and, within the resulting new project dialog, choose the Empty Views Activity template before clicking on the Next button.

Enter LifecycleDemo into the Name field and specify com.ebookfrenzy.lifecycledemo as the package name. Before clicking on the Finish button, change the Minimum API level setting to API 26: Android 8.0 (Oreo) and the Language menu to Kotlin.

Creating a Lifecycle Observer

As previously discussed, activities and fragments already implement the LifecycleOwner interface and are ready to be observed by other objects. To see this in practice, the next step in this tutorial is to add a new class to the project that will be able to observe the MainActivity instance.

To add the new class, right-click on app -> kotlin+java -> com.ebookfrenzy.lifecycledemo in the Project tool window and select New -> Kotlin Class/File… from the resulting menu. In the New Class dialog, name the class DemoObserver, select Class from the list, and press the keyboard Return key to create the DemoObserver.kt file. The new file should automatically open in the editor, where it will read as follows:

 

You are reading a sample chapter from Android Studio Giraffe Essentials – Kotlin Edition.

Buy the full book now in eBook (PDF) or Print format.

The full book contains 94 chapters and over 830 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

package com.ebookfrenzy.lifecycledemo
 
class DemoObserver {
}Code language: Kotlin (kotlin)

Remaining in the editor, modify the class file to declare that it will be implementing the DefaultLifecycleObserver interface:

package com.ebookfrenzy.lifecycledemo
 
import androidx.lifecycle.DefaultLifecycleObserver
 
class DemoObserver: DefaultLifecycleObserver {
}Code language: Kotlin (kotlin)

The next step is to override the lifecycle methods of the DefaultLifecycleObserver class. For this example, all events will be handled, each outputting a message to the Logcat panel displaying the event type. Update the observer class as outlined in the following listing:

package com.ebookfrenzy.lifecycledemo
 
import android.util.Log
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
 
class DemoObserver: DefaultLifecycleObserver {
 
    private val TAG = "DemoObserver"
 
    override fun onCreate(owner: LifecycleOwner) {
        Log.i(TAG, "onCreate")
    }
 
    override fun onResume(owner: LifecycleOwner) {
        Log.i(TAG, "onResume")
    }
 
    override fun onPause(owner: LifecycleOwner) {
        Log.i(TAG, "onPause")
    }
 
    override fun onStart(owner: LifecycleOwner) {
        Log.i(TAG, "onStart")
    }
 
    override fun onStop(owner: LifecycleOwner) {
        Log.i(TAG, "onStop")
    }
 
    override fun onDestroy(owner: LifecycleOwner) {
        Log.i(TAG, "onDestroy")
    }
}Code language: Kotlin (kotlin)

With the DemoObserver class completed, the next step is to add it as an observer on the MainActivity class.

Adding the Observer

Observers are added to lifecycle owners via calls to the addObserver() method of the owner’s Lifecycle object, a reference to which is obtained via a call to the getLifecycle() method. Edit the MainActivity.kt class file and edit the onCreate() method to add an observer:

.
.
import com.ebookfrenzy.lifecycledemo.DemoObserver
.
.
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
 
    lifecycle.addObserver(DemoObserver())
}Code language: Kotlin (kotlin)

With the observer class created and added to the lifecycle owner’s Lifecycle object, the app is ready to be tested.

 

You are reading a sample chapter from Android Studio Giraffe Essentials – Kotlin Edition.

Buy the full book now in eBook (PDF) or Print format.

The full book contains 94 chapters and over 830 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

Testing the Observer

Since the DemoObserver class outputs diagnostic information to the Logcat console, it will be easier to see the output if a filter is configured to display only the DemoObserver messages. Using the steps outlined previously in Android Activity State Changes Tutorial, display the Logcat panel and enter the following keys into the filter field:

package:mine tag:DemoObserverCode language: plaintext (plaintext)

On successful launch of the app, the Logcat output should indicate the following lifecycle state changes and events:

onCreate
onStart
onResumeCode language: plaintext (plaintext)

With the app still running, perform a device rotation to trigger the destruction and recreation of the activity, generating the following additional output:

onPause
onStop
onDestroy
onCreate
onStart
onResumeCode language: plaintext (plaintext)

Before moving to the next section in this chapter, take some time to compare the output from the app with the flow chart in Figure 45-2 of the previous chapter.

Creating a Lifecycle Owner

The final task in this chapter is to create a custom lifecycle owner class and demonstrate how to trigger events and modify the lifecycle state from within that class.

 

You are reading a sample chapter from Android Studio Giraffe Essentials – Kotlin Edition.

Buy the full book now in eBook (PDF) or Print format.

The full book contains 94 chapters and over 830 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

Add a new class by right-clicking on the app -> kotlin+java -> com.ebookfrenzy.lifecycledemo entry in the Project tool window and selecting the New -> Kotlin Class/File… menu option. Name the class DemoOwner in the Create Class dialog and select the Class option before tapping the keyboard Return key. With the new DemoOwner.kt file loaded into the code editor, modify it as follows:

package com.ebookfrenzy.lifecycledemo
 
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
 
class DemoOwner: LifecycleOwner(override val lifecycle: Lifecycle) {
}Code language: Kotlin (kotlin)

TThe class will need a LifecycleRegistry instance initialized with a reference to itself and a getLifecycle() method configured to return the LifecycleRegistry instance. Declare a variable to store the LifecycleRegistry reference and a constructor to initialize the LifecycleRegistry instance:

package com.ebookfrenzy.lifecycledemo
 
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
 
class DemoOwner(override val lifecycle: Lifecycle): LifecycleOwner {
 
   private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
 
   init {
 
   }
}Code language: Kotlin (kotlin)

Next, the class must notify the registry of lifecycle state changes. This can be achieved by marking the state with the markState() method of the LifecycleRegistry object or by triggering lifecycle events using the handleLifecycleEvent() method. What constitutes a state change within a custom class will depend on the purpose of the class. For this example, we will add some methods that trigger lifecycle events when called:

.
.
fun startOwner() {
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
}
 
fun stopOwner() {
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
}
.
.Code language: Kotlin (kotlin)

The last change within the DemoOwner class is to add the DemoObserver class as the observer. This call will be made by adding the following to the class constructor:

init {
    lifecycle.addObserver(DemoObserver())
}Code language: Kotlin (kotlin)

Load the MainActivity.kt file into the code editor, locate the onCreate() method, and add code to create an instance of the DemoOwner class and to call the startOwner() and stopOwner() methods. Note also that the call to add the DemoObserver as an observer has been removed. Although a single observer can be used with multiple owners, it is removed in this case to avoid duplicated and confusing output within the Logcat tool window:

 

You are reading a sample chapter from Android Studio Giraffe Essentials – Kotlin Edition.

Buy the full book now in eBook (PDF) or Print format.

The full book contains 94 chapters and over 830 pages of in-depth information.

Learn more.

Preview  Buy eBook  Buy Print

 

.
.
import com.ebookfrenzy.lifecycledemo.DemoOwner
.
.
private lateinit var demoOwner: DemoOwner
 
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
 
    demoOwner = DemoOwner(this.lifecycle)
    demoOwner.startOwner()
    demoOwner.stopOwner()
}Code language: Kotlin (kotlin)

Testing the Custom Lifecycle Owner

Build and run the app one final time, refer to the Logcat tool window, and confirm that the observer detected the create, start, and stop lifecycle events in the following order:

onCreate 
onStart 
onStop

Note that the “created” state changes were triggered even though code was not added to the DemoOwner class to do this manually. These were triggered automatically when the owner instance was first created and when the ON_STOP event was handled.

Summary

This chapter has provided a practical demonstration of implementing lifecycle awareness within an Android app, including creating a lifecycle observer and designing and implementing a basic lifecycle owner class.