In the Android world, many components have a life cycle, such as activities, fragments, etc. Before the Architecture Component came out, Activity/Fragment life cycle callbacks are used to perform activities in the corresponding life cycle, such as registering listeners, releasing resources, etc.

However, this approach is not very elegant. Originally, activities/fragments should only care about how to refresh the UI and send user interaction events to ViewModel/Presenter, not how to release resources at the end of their life cycle.

Android Jetpack addresses this problem by providing a series of lifecycle aware components that can migrate lifecycle logic to the components themselves that require the lifecycle. It makes each other’s responsibilities clearer.

For example, a lifecycle aware Listener works like this (pseudocode below)

class MyActivity : Activity() {
	override fun onCreate(...). {
	// Pass the Activity lifecycle to the Listener when the Activity destroys
	// This Listener will automatically unbind the Activity
        listener = MyLocationListener(this) { location ->
            // update UI
        }
	// No manual removeListener is required
        addListener(listener)
    }
}
Copy the code

Insert an AD here: a life-cycle aware EventBus with only 100 code implementations — LifecycleEventBus

How do I make my code implementation lifecycle aware

To implement the Lifecycle aware Listener, we first need to look at the Lifecycle class

Lifecycle

Lifecycle is a class that contains Lifecycle state information and allows other objects to listen for its Lifecycle state. Lifecycle has two main concepts: events and states.

Event

Events can be thought of as a series of lifecycle callback functions, such as onCreate()\onResume()\onPause() in an Activity, and so on

State

Created \ Started \ Destroyed refers to the lifecycle state of the current component, such as created\started\destroyed

LifecycleObserver

LifecycleObserver is, as the name suggests, a listener for Lifecycle, that is, a recipient of Lifecycle awareness, and we can use annotation methods in the Observer to listen for changes in the state of Lifecycle. For example, implement a lifecycle aware Listener

class LifecycleAwareListener(private val lifecycle: Lifecycle) : LifecycleObserver {
    
    init {
        lifecycle.addObserver(this)}fun onCallback(a){}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy(a) {
        // release resource}}Copy the code

How do I customize the View lifecycle

Lifecycle is implemented by default for activities and fragments, but some views don’t. Here’s an example: If we want to use life-cycle aware components in the ViewHolder of RecyclerView, such as LiveData, etc., Let’s define the ViewHolder life cycle to be consistent with the life cycle of the View to which it is attached — the View attaches to the View detach.

Before we get started, let’s take a look at the core classes LifecycleOwner and LifecycleRegistry

LifecycleOwner

This is a very simple interface

public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}
Copy the code

There is only one method that returns a Lifecycle. This interface defines that a class has a Lifecycle that can be listened on by other life-cycle-aware components (implementers of LifecycleObserver)

LifecycleRegistry

LifecycleRegistry This is a Lifecycle registry that inherits from Lifecycle. LifecycleOwner uses this class to distribute Lifecycle events and return them in getLifecycle(), as shown in the following code:

class LifecycleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LifecycleOwner {

    private val lifecycleRegistry: LifecycleRegistry by lazy { LifecycleRegistry(this)}fun onCreate(a) {
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

    fun onDestroy(a) {
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
    }

    override fun getLifecycle(a): Lifecycle {
        return lifecycleRegistry
    }

}
Copy the code

A ViewHolder with a life cycle is then born, but where to call onCreate())\onDestroy()? Having said that, we can define the ViewHolder life cycle to be consistent with the life cycle of the View to which it is bound

class LifecycleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LifecycleOwner {

    init {
        itemView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
            // View onDetached time callback onDestroy()
            override fun onViewDetachedFromWindow(v: View?). {
                itemView.removeOnAttachStateChangeListener(this)
                onDestroy()
            }

            // Call onCreate() when View onAttached
            override fun onViewAttachedToWindow(v: View?). {
                onCreate()
            }
        })
    }

    private val lifecycleRegistry: LifecycleRegistry by lazy { LifecycleRegistry(this)}fun onCreate(a) {
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

    fun onDestroy(a) {
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
    }

    override fun getLifecycle(a): Lifecycle {
        return lifecycleRegistry
    }

}
Copy the code

Lifecycle aware components such as LiveData can then be used in the ViewHolder as activities and fragments

class MyViewHolder(view: View, private val viewModel: MvvmViewModel) : LifecycleViewHolder(view) {

    override fun onCreate(a) {
        super.onCreate()
        viewModel.uiModel.observe(this, Observer {
            println(it.name)
        })
    }

}
Copy the code

Reference article:

Handling Lifecycles with Lifecycle-Aware Components

Other related articles:

Proper use of LiveData posture and anti-patterns

Use the Architecture Component to implement the proper posture of the MVVM

The exploration and attempt of LiveData non-sticky message

How to implement a life-cycle aware EventBus in 100 lines of code