一文带你了解 Lifecycle (使用篇) | 开发者说·DTalk

2019 年 9 月 18 日 谷歌开发者
本文原作者: 刘望舒,原文发布于公众号后厂村刘皇叔: https://mp.weixin.qq.com/s/TmI0O4OsvdD6DHkLm9EiiQ


前言

在上一篇文章 (《一文带你了解 Android Jetpack | 开发者说·DTalk》) 中,我们基本了解了什么是 Android Jetpack,这一篇文章来介绍 Android Jetpack 架构组件的 Lifecycle,Lifecycle 用于帮助开发者管理 Activity 和 Fragment 的生命周期,由于 Lifecycle 是 LiveData 和 ViewModel 的基础,所以需要先学习它。


1. 为什么需要 Lifecycle

在应用开发中,处理 Activity 或者 Fragment 组件的生命周期相关代码是必不可免的。

官方文档中举了一个例子,这里简化一下,在 Activity 中写一个监听,在 Activity 的不同生命周期方法中调用这个监听。

public class MainActivity extends AppCompatActivity {
    private MyListener myListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myListener = new MyListener(MainActivity.this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        myListener.start();
    }

    @Override
    protected void onStop() {
        super.onStop();
        myListener.stop();
    }
}


class MyListener {
    public MyListener(Context context) {
    ...
    }
    void start() {
    ...
    }
    void stop() {
    ...
    }
}

再举个 MVP 中常见的情况,如下所示。

public class MainActivity extends AppCompatActivity {
    private MyPresenter myPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myPresenter = new MyPresenter();
    }

    @Override
    protected void onResume() {
        super.onResume();
        myPresenter.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        myPresenter.onPause();
    }
}

class MyPresenter{
    void onResume() {
    ...
    }
    void onPause() {
    ...
    }
}
这两个例子的写法已经很普遍了,实现起来也不难,但实际开发中,可能会有多个组件在 Activity 的生命周期中进行回调,这样 Activity 的生命周期的方法中可能就需要放大量的代码,这就使得它们难以维护。


还有一个问题是,如果我们在组件中做了耗时操作 (比如在 onStart 方法),这种写法就无法保证组件在 Activity 或者 Fragment 停止之前完成启动。


因此我们需要一个能管理 Activity 和 Fragment 的生命周期的库,这个库就是 Lifecycle。


2. 如何使用 Lifecycle

分别来介绍下依赖 Lifecycle 库和 Lifecycle 基本用法。


2.1 依赖 Lifecycle 库

官网给出的依赖代码如下所示: 
dependencies {
    def lifecycle_version = "2.0.0"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx

    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}

官网用的是 AndroidX,因为使用 AndroidX,可能会产生一些迁移的问题,这里的举例就不使用 AndroidX,而是使用 lifecycleandroid.arch.lifecycle 库,如下所示。

dependencies {
    def lifecycle_version = "1.1.1"

    // 包含ViewModel和LiveData
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    // 仅仅包含ViewModel
    implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" // For Kotlin use viewmodel-ktx
    // 仅仅包含LiveData
    implementation "android.arch.lifecycle:livedata:$lifecycle_version"
    // 仅仅包含Lifecycles
    implementation "android.arch.lifecycle:runtime:$lifecycle_version"

    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
    // 如果用Java8, 用于替代compiler
    implementation "android.arch.lifecycle:common-java8:$lifecycle_version"

    // 可选,ReactiveStreams对LiveData的支持
    implementation "android.arch.lifecycle:reactivestreams:$lifecycle_version"

    // 可选,LiveData的测试
    testImplementation "android.arch.core:core-testing:$lifecycle_version"
}
实际上我们不需要全部把这些代码全写进 build.gralde 进去 (当然全写进去也不会有什么错),因为 Gradle 默认是支持依赖传递的,不知道什么是依赖传递的看 Android Gradle (二) 签名配置和依赖管理这篇文章。


我们直接添加如下依赖就可以满足日常的工作,如果缺少哪个库,再去单独添加就好了。

implementation "android.arch.lifecycle:extensions:1.1.1"

添加这一句代码就依赖了如下的库。

2.2 Lifecycle 基本用法

先不谈 Activity 和 Fragment 中如何使用,先举一个 Lifecycle 的简单例子。

   
   
     
public  class MyObserver implements LifecycleObserver {
     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
     public void connectListener() {
        ...
    }

     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
     public void disconnectListener() {
        ...
    }
}

myLifecycleOwner.getLifecycle().addObserver( new MyObserver()); //1

新建一个 MyObserver 类,它实现了 LifecycleObserver 接口,说明 MyObserver 成为了一个 Lifecycle 的观察者。


然后在注释 1 处将 MyObserver 添加到 LifecycleOwner 中。LifecycleOwner 是一个接口,其内部只有一个方法 getLifecycle(),getLifecycle 方法用于获取 Lifecycle,这样就可以将 MyObserver 添加到 Lifecycle 中,当 Lifecycle 的生命周期发生变化时,MyObserver 就会观察到,或者说是感知到。


如果使用是 Java8 , 那么可以使用 DefaultLifecycleObserver 来替代 LifecycleObserver: 

   
   
     
class MyObserver implements DefaultLifecycleObserver {
      @Override
      public void onCreate(LifecycleOwner owner) {
         ...
     }
 }

除此之外,不要忘了在 build.gradle 添加"androidx.lifecycle:common-java8:<version>"


3. Lifecycle 应用举例

应用举例准备两个示例,一个是在 Activity 中使用,一个是在第一小节的 MVP 例子上进行改进。


3.1 Activity 中使用

package com.example.lifecycledemo1;

import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getLifecycle().addObserver(new MyObserver());//1
    }

    public class MyObserver implements LifecycleObserver{

        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        void onResume(){
            Log.d(TAG, "Lifecycle call onResume");
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        void onPause(){
            Log.d(TAG, "Lifecycle call onPause");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");

    }
}

先实现 MyObserver,对 ON_CREATE 和 ON_RESUME 事件进行监听。因为在 Android Support Library 26.1.0 及其之后的版本,Activity 和 Fragment 已经默认实现了LifecycleOwner 接口,所以在注释 1 处可以直接使用 getLifecycle 方法获取 Lifecycle 对象,这样 MyObserver 就可以观察 MainActivity 的生命周期变化了,LifecycleOwner 可以理解为被观察者,MainActivity 默认实现了 LifecycleOwner 接口,也就是说 MainActivity 是被观察者。


运行程序,打印的 log 如下所示。

   
   
     
D/MainActivity: onResume
D/MainActivity: Lifecycle call onResume
D/MainActivity: Lifecycle call onPause
D/MainActivity: onPause

只要在 MainActivity 的 onCreate 方法中添加 MyObserver,那么 MyObserver 就可以观察到 MainActivity 的各个生命周期的变化。


3.2 MVP 中使用

改写第一小节 MVP 的例子,先实现 MyPresenter,如下所示。

   
   
     
public  class MyPresenter implements IPresenter {
     private  static  final String TAG =  "test";

     @Override
     public void onResume() {
        Log.d(TAG,  "Lifecycle call onResume");
    }

     @Override
     public void onPause() {
        Log.d(TAG,  "Lifecycle call onPause");
    }
}

interface IPresenter extends LifecycleObserver {

     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
     void onResume();

     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
     void onPause();
}

IPresenter 接口继承自 LifecycleObserver 接口,MyPresenter 又实现了 IPresenter 接口,这样 MyPresenter 成为了一个观察者。


接着在 MainActivity 中加入 MyPresenter: 

   
   
     
public  class MainActivity extends AppCompatActivity {

     private  static  final String TAG =  "test";
     private IPresenter mPresenter;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mPresenter =  new MyPresenter();
        getLifecycle().addObserver(mPresenter);
    }

     @Override
     protected void onResume() {
         super.onResume();
        Log.d(TAG,  "onResume");
    }

     @Override
     protected void onPause() {
         super.onPause();
        Log.d(TAG,  "onPause");

    }
}

MainActivity 成为了被观察者,当它的生命周期发生变化时,MyPresenter 就可以观察到,这样就不需要在 MainActivity 的多个生命周期方法中调用 MyPresenter 的方法了。


打印的日志如下:

   
   
     
D/test: onResume
D/test: Lifecycle call onResume
D/test: Lifecycle call onPause
D/test: onPause

4. 自定义 LifecycleOwner

如果想实现自定义 LifecycleOwner,可以使用 LifecycleRegistry,它是 Lifecycle 的实现类。Android Support Library 26.1.0及其之后的版本,Activity 和 Fragment 已经默认实现了 LifecycleOwner 接口,因此我们可以这么写:

   
   
     
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleRegistry;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public  class MyActivity extends AppCompatActivity {
     private LifecycleRegistry lifecycleRegistry;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

        lifecycleRegistry =  new LifecycleRegistry( this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

     @Override
     public void onStart() {
         super.onStart();
        lifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

     @NonNull
     @Override
     public Lifecycle getLifecycle() {
         return lifecycleRegistry;
    }
}

通过新建 LifecycleRegistry,为 LifecycleRegistry 设置 Lifecycle 的各种状态,并通过 getLifecycle 方法返回该 LifecycleRegistry。


总结

这一篇介绍了 Lifecycle 的基本用法,并通过两个小例子来帮助大家消化理解,具体在项目中的使用也不难,唯一还算难点的是 Lifecycle 的原理,下一篇我们就来学习 Lifecycle 的原理。




"开发者说·DTalk" 面向中国开发者们征集 Google 移动应用 (apps & games) 相关的产品/技术内容。欢迎大家前来分享您对移动应用的行业洞察或见解、移动开发过程中的心得或新发现、以及应用出海的实战经验总结和相关产品的使用反馈等。我们由衷地希望可以给这些出众的中国开发者们提供更好展现自己、充分发挥自己特长的平台。我们将通过大家的技术内容着重选出优秀案例进行谷歌开发技术专家 (GDE) 的推荐。


 点击屏末 |  | 了解更多 "开发者说·DTalk" 活动详情与参与方式


长按右侧二维码

报名参与




登录查看更多
1

相关内容

Android(安卓)是一种以 Linux 为基础开发的开放源代码的操作系统,主要应用于便携设备。2005 年,Android 公司被 Google 收购,随后 Google 联合制造商组成开放手机联盟。Android 已从智能手机领域逐渐扩展到平板电脑、智能电视(及机顶盒)、游戏机、物联网、智能手表、车载系统、VR以及PC等领域。
专知会员服务
54+阅读 · 2020年7月4日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
大数据安全技术研究进展
专知会员服务
92+阅读 · 2020年5月2日
强化学习最新教程,17页pdf
专知会员服务
174+阅读 · 2019年10月11日
机器学习入门的经验与建议
专知会员服务
92+阅读 · 2019年10月10日
TensorFlow 2.0 学习资源汇总
专知会员服务
66+阅读 · 2019年10月9日
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
2020年你应该知道的8种前端JavaScript趋势和工具
前端之巅
5+阅读 · 2019年6月9日
iOS自定义带动画效果的模态框
CocoaChina
7+阅读 · 2019年3月3日
请快点粘贴复制,这是一份好用的TensorFlow代码集
C# 10分钟完成百度人脸识别
DotNet
3+阅读 · 2019年2月17日
开发者应当了解的18套机器学习平台
深度学习世界
5+阅读 · 2018年8月14日
号称“开发者神器”的GitHub,到底该怎么用?
算法与数据结构
4+阅读 · 2018年3月29日
十五条有用的Golang编程经验
CSDN大数据
5+阅读 · 2017年8月7日
基于LDA的主题模型实践(三)
机器学习深度学习实战原创交流
23+阅读 · 2015年10月12日
Arxiv
101+阅读 · 2020年3月4日
Semantics of Data Mining Services in Cloud Computing
Arxiv
4+阅读 · 2018年10月5日
Rapid Customization for Event Extraction
Arxiv
7+阅读 · 2018年9月20日
VIP会员
相关VIP内容
专知会员服务
54+阅读 · 2020年7月4日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
大数据安全技术研究进展
专知会员服务
92+阅读 · 2020年5月2日
强化学习最新教程,17页pdf
专知会员服务
174+阅读 · 2019年10月11日
机器学习入门的经验与建议
专知会员服务
92+阅读 · 2019年10月10日
TensorFlow 2.0 学习资源汇总
专知会员服务
66+阅读 · 2019年10月9日
相关资讯
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
2020年你应该知道的8种前端JavaScript趋势和工具
前端之巅
5+阅读 · 2019年6月9日
iOS自定义带动画效果的模态框
CocoaChina
7+阅读 · 2019年3月3日
请快点粘贴复制,这是一份好用的TensorFlow代码集
C# 10分钟完成百度人脸识别
DotNet
3+阅读 · 2019年2月17日
开发者应当了解的18套机器学习平台
深度学习世界
5+阅读 · 2018年8月14日
号称“开发者神器”的GitHub,到底该怎么用?
算法与数据结构
4+阅读 · 2018年3月29日
十五条有用的Golang编程经验
CSDN大数据
5+阅读 · 2017年8月7日
基于LDA的主题模型实践(三)
机器学习深度学习实战原创交流
23+阅读 · 2015年10月12日
Top
微信扫码咨询专知VIP会员