LifeCycle
LifeCycle is a component that can sense changes in the LifeCycle of the host. Common hosts include activities/fragments, services, and applications. LifeCycle holds information about the host’s LifeCycle state and notifies observers listening to the host when the host’s LifeCycle changes.
LifeCycle arises primarily to address the coupling between the LifeCycle of system components and ordinary components.
- System components include activities, fragments, services, and Applications.
- Common components: components that encapsulate code in terms of function or function.
In what cases is the life cycle of a system component coupled to the life cycle of a normal component?
Here’s an example:
There is a business need for video playback in the 58 tribe business. We need to initialize the video component in the Activity, stop the video in the onPause() method, and reclaim the video component and some resources in the onDestroy() method. Doing so is tedious and makes the coupling between the page and the components higher.
This is the kind of problem that LifeCycle can fully solve. It not only reduces the degree of coupling between modules, but also reduces the possibility of memory leaks.
(2) Use of LifeCycle
Jetpack provides us with two interfaces:
Observed: LifecycleOwner
Observer: LifecycleObserver
The listening system component needs to implement the LifecycleOwner interface, and the observer needs to implement the LifecycleObserver interface.
Use Scenario 1: Use LifeCycle to decouple pages from components
(1) Decouple activities
Step 1: Add dependencies
implementation 'androidx. Appcompat: appcompat: 1.2.0'
Copy the code
In AndroidX ComponentActivity already implements the LifecycleOwner interface by default. If the project does not migrate to AndroidX, the Support library will still be used. The new SDK also implements the LifecycleOwner interface through SupportActivity.
In the LifecycleOwner interface, there is only one getLifecycle method.
Step 2: Implement the observer
If we want to listen to the lifecycle of an Activity, all we need to do is customize the component and implement the LifecycleObserver interface. This interface has no interface methods and does not require any specific implementation.
For example, take the video just played:
- Create a MyVideoPlayListener class that implements the LifecycleObserver interface, and do all the video playing-related logic in this class. Methods in the component that need to be notified when the Activity Lifecycle changes are marked with the @onlifecycleEvent (lifecyc.event.on_xxx) annotation so that when the Activity Lifecycle changes, The marked method is automatically called.
public class MyVideoPlayListener implements LifecycleObserver {
private static String TAG = "MyVideoPlayListener";
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void initVideo(a){
Log.d(TAG,"initVideo");
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private void startPlay(a){
Log.d(TAG,"startPlay");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private void pausePlay(a){
Log.d(TAG,"pausePlay"); }}Copy the code
2. Reference MyVideoPlayListener in MainActivity.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyVideoPlayListener listener = newMyVideoPlayListener(); getLifecycle().addObserver(listener); }}Copy the code
(2) Decouple fragments
In the new VERSION of the SDK, fragments also implement the LifecycleOwner interface by default, so the above example applies to fragments as well.
Scenario 2: Use LifecycleService to decouple services from components
(1) LifecycleService Basic introduction
In addition to activities/fragments, a very important component that has a lifecycle in Android is a Service. LifecycleService is used to listen to and decouple Service components.
public class LifecycleService extends Service implements LifecycleOwner {
private final ServiceLifecycleDispatcher mDispatcher = new ServiceLifecycleDispatcher(this); .@Override
@NonNull
public Lifecycle getLifecycle(a) {
returnmDispatcher.getLifecycle(); }}Copy the code
(2) The specific use method
Step 1: Add related dependencies
implementation "Androidx. Lifecycle: lifecycle - service: 2.2.0." "
Copy the code
Step 2: Create the MyServiceObserver class to implement the LifecycleObserver interface. Use the @onlifecyCleEvent tag for methods you want to get called synchronously when the Server lifecycle changes.
public class MyServiceObserver implements LifecycleObserver {
private static String TAG = "MyServiceObserver";
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void initVideo(a){
Log.d(TAG,"initVideo");
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private void pausePlay(a){
Log.d(TAG,"stopPlay"); }}Copy the code
Step 3: Create a MyService class that inherits from LifecycleService. Because LifecycleService is a direct subclass of Service, it is used no differently than a normal Service.
public class MyService extends LifecycleService {
private MyServiceObserver myServiceObserver;
public MyService(a){
myServiceObserver = newMyServiceObserver(); getLifecycle().addObserver(myServiceObserver); }}Copy the code
Usage scenario 3: Use ProcessLifecycleOwner to listen for the life cycle of an application
In addition to activities, fragments, and services, components that have lifecycles include applications. ProcessLifecycleOwner is used to listen for the entire application lifecycle.
Specific use method:
Step 1: Add dependencies
implementation "Androidx. Lifecycle: lifecycle - process: 2.2.0." "
Copy the code
Step 2: Define an ApplicationObserver that implements the LifecycleObserver interface.
public class ApplicationObserver implements LifecycleObserver {
private String TAG = this.getClass().getName();
/** * will only be called once */ during the lifetime of the application
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate(a) {
Log.d(TAG,"Lifecycle.Event.ON_CREATE");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart(a) {
Log.d(TAG,"Lifecycle.Event.ON_START");
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume(a) {
Log.d(TAG,"Lifecycle.Event.ON_RESUME");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause(a) {
Log.d(TAG,"Lifecycle.Event.ON_PAUSE");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop(a) {
Log.d(TAG,"Lifecycle.Event.ON_STOP");
}
/** * will never be called, the system will not distribute the call ON_DESTROY event */
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy(a) {
Log.d(TAG,"Lifecycle.Event.ON_DESTROY"); }}Copy the code
Step 3: Associate ApplicationObserver in Application.
public class App extends Application {
@Override
public void onCreate(a) {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(newApplicationObserver()); }}Copy the code
Notes:
- ProcessLifecycleOwner is listening for the entire application, regardless of the number of activities.
- Lifecycle. Event.on_create will be called only once and Lifecycle. Event.on_destroy will never be called.
- There will be a delay in calling Lifecycle. Event.on_pause and Lifecycle. Event.on_stop because the system needs to allow time for “screen rotation, Activity re-creation due to configuration changes”.
There are two other ways of writing LifeCycle
LifeCycle can be implemented in three ways:
- LifecycleObserver cooperate
@OnLifecycleEvent
annotations - DefaultLifecycleObserver hosts all life cycle events
- LifecycleEventObserver encapsulates host Lifecycle events as lifecyc.event
In the previous usage introduction, we used the first approach: LifecycleObserver with the @onlifecyCleEvent annotation.
This is easy to use, but it is better to add lifecycle compiler as an annotation handler, or use reflection to call back to the corresponding method at runtime:
annotationProcessor "Androidx. Lifecycle: lifecycle - compiler: 2.2.0." "
Copy the code
With this annotation handler, methods marked with @onlifecyCleEvent can no longer be declared private, or the following error will be reported:
method marked with OnLifecycleEvent annotation can not be private
Copy the code
Here are two other implementations:
DefaultLifecycleObserver hosts all life cycle events
Using DefaultLifecycleObserver requires using Java8, we first add a dependency:
Implementation "androidx lifecycle: lifecycle - common - java8:2.2.0." "Copy the code
Then in the build.gradle at the module level add:
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Copy the code
With the lifecycle common-Java 8 dependency, the lifecycle compiler dependency can be removed.
There are six lifecycle methods in the DefaultLifecycleObserver interface:
public interface DefaultLifecycleObserver extends FullLifecycleObserver {
@Override
default void onCreate(@NonNull LifecycleOwner owner) {}@Override
default void onStart(@NonNull LifecycleOwner owner) {}@Override
default void onResume(@NonNull LifecycleOwner owner) {}@Override
default void onPause(@NonNull LifecycleOwner owner) {}@Override
default void onStop(@NonNull LifecycleOwner owner) {}@Override
default void onDestroy(@NonNull LifecycleOwner owner) {}}Copy the code
This interface inherits from the FullLifecycleObserver, which we cannot use directly to own all of the hosted lifecycle events due to permission issues.
So, we need to override the lifecycle methods that our business needs to listen to by implementing the DefaultLifecycleObserver interface.
(2) LifecycleEventObserver hosts Lifecycle events encapsulated as lifecyc.event
// Override the onStateChanged method, inside the method, by implementing the LifecycleEventObserver interface
// Implement specific business logic by determining Lifecycle.Event
public class MyVideoPlayObserver implements LifecycleEventObserver {
private static String TAG = "MyVideoPlayObserver";
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
switch (event){
case ON_CREATE:
Log.d(TAG,"initVideo");
break;
case ON_START:
Log.d(TAG,"startPlay");
break;
case ON_RESUME:
Log.d(TAG,"resumePlay");
break;
default:
break; }}}Copy the code
How to choose these three implementations?
DefaultLifecycleObserver and LifecycleEventObserver are recommended.
- Java8 uses a DefaultLifecycleObserver to implement Lifecycle and Java7 uses annotations. The annotated approach will be deprecated once Java8 becomes mainstream on Android.
- If a class implements both the DefaultLifecycleObserver interface and the LifecycleEventObserver interface, then the methods in the DefaultLifecycleObserver will fire first, The LifecycleEventObserver’s onStateChanged method is then executed.
- If a class implements the DefaultLifecycleObserver interface, it also uses the
@OnLifecycleEvent
Annotation, then the annotation mode is automatically ignored.
Four,
The main purpose of LifeCycle components is to help us decouple them so that the components we define can also feel the LifeCycle changes.
Five, the complement
As of this release, the latest version of lifecycle_version is 2.2.0. If you need to obtain the latest version, please check the official website:
Developer. The android. Google. Cn/jetpack/and…
The lifecycle-Extensions API is deprecated. If one of the tools available at lifecycle needs to be used, add a dependency:
dependencies {
def lifecycle_version = "2.2.0"
def arch_version = "2.1.0."
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}
Copy the code
6. Reference materials
Official Google Jetpack documentation
Moocs: Learn Jetpack from an architect
The Android Jetpack App Guide by Ye Kun