Customize life cycle and realize life cycle awareness

In the Android world, many components have a life cycle, such as Activity and Fragment. Before the Architecture Component came out, we used the life cycle callback function of Activity/Fragment to do corresponding operations in the corresponding life cycle, such as registering, listening, releasing resources, etc.

However, this method is not so elegant. Originally, the Activity/Fragment should only care about how to refresh the UI and send the user's interactive behavior events to the ViewModel/Presenter, rather than how to release resources at the end of the life cycle.

Android Jetpack provides a series of lifecycle aware components (components with life cycle awareness) to solve this problem. These life cycle related logic can be migrated to the components that need these life cycles, making their responsibilities clearer.

For example, a Listener with life cycle awareness can be used like this (the following is pseudo code)

class MyActivity : Activity() {
	override fun onCreate(...) {
	// Pass the Activity lifecycle to the Listener when the Activity destroy s
	// This Listener will be automatically unbound from the Activity 
        listener = MyLocationListener(this) { location ->
            // update UI
        }
	// Manual removeListener is not required
        addListener(listener)
    }
}
Copy code

Insert an advertisement here: an EventBus with life cycle awareness implemented in only 100 code—— LifecycleEventBus

How to make code implementation have life cycle awareness

To implement the above Listener with life cycle awareness, we must first understand the Lifecycle class

Lifecycle

Lifecycle is a class containing lifecycle State information, which allows other objects to listen to its lifecycle State; Lifecycle has two main concepts: Event and State

Event

Events can be understood as a series of life cycle callback functions, such as onCreate()\onResume()\onPause() in Activity, etc

State

Refers to the life cycle state of the current component, such as created\started\destroyed, etc

LifecycleObserver

LifecycleObserver, as its name implies, is the Listener of Lifecycle, that is, the winner of Lifecycle awareness. We can use corresponding annotation methods in the Observer to monitor Lifecycle state changes, such as implementing a Listener with Lifecycle awareness

class LifecycleAwareListener(private val lifecycle: Lifecycle) : LifecycleObserver {
    
    init {
        lifecycle.addObserver(this)
    }

    fun onCallback() {

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        // release resource
    }
}
Copy code

How to customize the life cycle for View

Activity and Fragment have implemented Lifecycle by default, but some views do not. For example, if we want to use Lifecycle aware components in ViewHolder in RecyclerView, such as LiveData, Let's define the life cycle of the ViewHolder to be consistent with the life cycle of the view to which it is bound -- view attach to view detach.

Before we begin, let's take a look at the core classes lifecycle owner and lifecycle registry

LifecycleOwner

This is a particularly simple interface

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

There is only one method to return a Lifecycle. This interface defines that a class has a Lifecycle, and the returned Lifecycle can be monitored by other components with Lifecycle awareness (implementers of Lifecycle observer)

LifecycleRegistry

LifecycleRegistry This is a Lifecycle registrar, which inherits from Lifecycle. The Lifecycle owner distributes Lifecycle events through this class and returns them in getLifecycle(). For example, the following code:

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

    private val lifecycleRegistry: LifecycleRegistry by lazy { LifecycleRegistry(this) }

    fun onCreate() {
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

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

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }

}
Copy code

Such a ViewHolder with a life cycle is born, but where to call the methods onCreate())\onDestroy()? As mentioned earlier, we can define the life cycle of the ViewHolder to be consistent with the life cycle of the View it is bound to

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

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

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

    private val lifecycleRegistry: LifecycleRegistry by lazy { LifecycleRegistry(this) }

    fun onCreate() {
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

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

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }

}
Copy code

Then you can use LiveData and other life cycle aware components in ViewHolder like Activity and Fragment

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

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

}
Copy code

Reference article:

Handling Lifecycles with Lifecycle-Aware Components

Other related articles:

Correct use of LiveData, posture and anti pattern

Using Architecture Component to realize the correct posture of MVVM

Exploration and attempt of LiveData non sticky message

Teach you how to implement an EventBus with life cycle awareness with 100 lines of code

Added by capitala on Thu, 09 Dec 2021 06:45:22 +0200