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