Lifecycle官方文档地址:https://developer.android.com/topic/libraries/architecture/lifecycle

一、为什么要使用Lifecycle?

Activity 和 Fragment 是有声明周期的,开发时我们的很多操作需要写在声明周期的方法中,比如,下载、文件操作等。这样很多情况下会导致,我们在 Activity中 的声明周期方法中写越来越多的代码,从而使得 Activity 或者 Fragment 越来越臃肿,代码维护越来越困难。这时我们使用Lifecycle就可以很好的解决这类问题。
Lifecycle代码简洁,我们可以通过实现LifecycleObserver 接口来监听声明周期,然后我们在Activity和Fragment中去注册监听。

Lifecycle 的原理图如下:

看完原理图后,我们应该对Lifecycle有一些简单的理解和认知了,下面我们来讲述一下Lifecycle如何使用。

二、Lifecycle 的使用说明

2.1 几个重要的类和接口

Lifecycle Lifecycle是一个持有组件生命周期状态(如Activity或Fragment)的信息的类,并允许其他对象观察此状态。

Event :从框架和Lifecycle类派发的生命周期事件。这些事件映射到活动和片段中的回调事件。

State :由Lifecycle对象跟踪的组件的当前状态。

LifecycleOwner (重要)Lifecycle持有者:实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。

LifecycleObserver(重要)Lifecycle观察者:实现该接口的类,通过注解的方式,可以通过被LifecycleOwner类的addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

2.2 LifeCycleOwner 和 LifecycleObserver

(1). LifecycleOwner(生命周期持有者接口)

简单来说,LifecycleOwner 就是一个接口,谁继承了它,就持有了lifecycle对象。然后就可以调用getLifecycle()方法获取继承了抽象类Lifecycle的LifecycleRegistry,然后调用 addObserver(@NonNull LifecycleObserver observer) 方法来注册监听。
这样,该接口的生命周期 (Lifecycle对象) 的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。

注意:Support Library 26.1.0 及其以后的版本,Activity 和Fragment 已经实现了LifecycleOwner 接口。我们可以直接在Activity 和Fragment中使用getLifecycle()方法来获取 Lifecycle 对象,来添加观察者监听。

(2). LifecycleObserver(生命周期观察者接口)

LifecycleObserver 是一个观察者接口,实现了它,可以通过注解或者继承的方式,来管理声明周期的监听。只要在持有lifecycle的类中注册了它,当声明周期发生变化时,它就能收到,进行我们自定义的操作。

三、Lifecycle 实战

目前Activity可以不用实现 LifecycleOwner,从API14开始 AppCompatActivity已经在内部实现了 LifecycleOwner,我们只需要使用AppCompatActivity结合Lifecycle一起使用即可。

页面代码:

public class MainActivity extends AppCompatActivity {

    MyObserver myObserver;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myObserver = new MyObserver();
getLifecycle().addObserver(myObserver);
} public void toSecond(View view) {
startActivity(new Intent(this, SecondActivity.class));
} @Override
protected void onDestroy() {
super.onDestroy();
getLifecycle().removeObserver(myObserver);
}
}

组件监听代码:

package com.renhui.lifecycle;

import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent; public class MyObserver implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void ON_CREATE() {
System.out.println("MyObserver:ON_CREATE");
} @OnLifecycleEvent(Lifecycle.Event.ON_START)
public void ON_START() {
System.out.println("MyObserver:ON_START");
} @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void ON_RESUME() {
System.out.println("MyObserver:ON_RESUME");
} @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void ON_PAUSE() {
System.out.println("MyObserver:ON_PAUSE");
} @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void ON_STOP() {
System.out.println("MyObserver:ON_STOP");
} @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void ON_DESTROY() {
System.out.println("MyObserver:ON_DESTROY");
}
}

Demo地址:https://github.com/renhui/LiftCycle-master

四、进阶用法

我们可以在初始化MyObserver的时候将lifecycle传入,在MyObserver中进行操作时再次确认宿主的”生命周期”状态。

if (lifecycle.getCurrentState().isAtLeast(STARTED)) {
  //do something
}

另外,官网提供了生命周期感知组件的最佳实战的建议:

  1. 尽可能保持您的UI控制器(活动和片段)尽可能精简。他们不应该试图获取他们自己的数据;相反,使用ViewModel来做到这一点,并观察一个LiveData对象来反映更改回视图。
  2. 尝试编写数据驱动的用户界面,其中您的用户界面控制器的职责是在数据更改时更新视图,或将用户操作通知给ViewModel。
  3. 把你的数据逻辑放在ViewModel类中。ViewModel应作为您的UI控制器和其他应用程序之间的连接器。但要小心,ViewModel不负责提取数据(例如,来自网络)。相反,ViewModel应调用相应的组件来获取数据,然后将结果提供给UI控制器。
  4. 使用dataBinding在视图和UI控制器之间保持干净的界面。这使您可以使您的视图更具说明性,并最大限度地减少需要在活动和片段中编写的更新代码。

如果你喜欢用Java编程语言来做到这一点,可以使用像Butter Knife这样的库来避免样板代码并且有更好的抽象。

  1. 如果您的UI很复杂,请考虑创建一个演示者类(presenter)来处理UI修改。这可能是一项艰巨的任务,但它可以使您的UI组件更易于测试。
  2. 避免在ViewModel中引用View或Activity上下文。

如果ViewModel超出活动(在配置更改的情况下),则活动会泄漏并且垃圾收集器无法正确处理。

Android框架式编程之Lifecycle的更多相关文章

  1. Android框架式编程之Android Architecture Components

    1. 当前Android开发面临的问题 Android开发不同于传统的桌面程序开发,桌面程序一般都有唯一的快捷方式入口,并且常作为单进程存在:而一个典型的Android应用通常由多个应用组件构成,包括 ...

  2. Android框架式编程之BufferKnife

    配置 compile 'com.jakewharton:butterknife:(insert latest version)' annotationProcessor 'com.jakewharto ...

  3. Android框架式编程之RxJava(一):HelloWorld

    Hello World 源码: import android.graphics.Bitmap; import android.graphics.BitmapFactory; import androi ...

  4. Android框架式编程之Room

    Room是Google官方出品的ORM(Object-relational mapping) 框架.当前我们也知道当前还有很多的ORM框架,例如GreenDao.OrmLite.Litepal等.目前 ...

  5. Android框架式编程之Retrofit

    一.Retrofit 简介 Retrofit 官网地址: https://github.com/square/retrofit Retrofit(即Retrofit,目前最新版本为2.6.0版本),是 ...

  6. Android框架式编程之LiveData

    一.LiveData 介绍 LiveData是 Google 推荐的 Android 架构组件之一,是一个基于观察者模式的数据容器,但与一般的被观察者不同的是,它是有生命周期感知功能,解决了Andro ...

  7. Android框架式编程之EasyPermissions

    EasyPermission库是一个谷歌官方提供的简化基本的系统权限逻辑的库,可用于在Android M或者更高版本上. 官方项目地址:https://github.com/googlesamples ...

  8. Android框架式编程之EventBus

    一.EventBus 简介 EventBus是一种用于Android的事件发布-订阅总线,由GreenRobot开发,Gihub地址是:EventBus. 它简化了应用程序内各个组件之间进行通信的复杂 ...

  9. Android框架式编程之MVP架构

    MVP(Model-View-Presenter)模式.是将APP的结构分为三层:View - Presenter - Model. View 1. 提供UI交互 2. 在presenter的控制下修 ...

随机推荐

  1. DRF Django REST framework 之 序列化(三)

    Django 原生 serializer (序列化) 导入模块 from django.core.serializers import serialize 获取queryset 对queryset进行 ...

  2. 使用正则表达式实现(加减乘除)计算器(C#实现)

    起因:公司领导要求做一款基于行业规范的计算器, 然后需要用户输入一些数据,然后根据用户输入的数据满足某些条件后,再根据用户输入的条件二进行加减乘除运算.;-) 期间因为查找规范等形成数据表的某一列是带 ...

  3. set容器

    set容器简介: 1) set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列.元素插入过程是按排序规则插入,所以不能指定插入位置. 2) set采用红黑树变体的数据结构实现,红 ...

  4. luogu P4408 [NOI2003]逃学的小孩

    题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听说要考试,Chris的父母就心 ...

  5. k8s 开船记-首航:博客站点从 docker swarm 切换到 k8s

    昨天晚上,我们将博客站点的生产环境从 docker swarm 集群切换到了 k8s 集群,开船到目前,航行非常平稳,可以说首航成功! k8s 集群是我们用10台阿里云服务器自己搭建的,1台 mast ...

  6. Redis 命令执行过程(下)

    在上一篇文章中<Redis 命令执行过程(上)>中,我们首先了解 Redis 命令执行的整体流程,然后细致分析了从 Redis 启动到建立 socket 连接,再到读取 socket 数据 ...

  7. [Python Modules] unittest.mock

    五夜光寒,照来积雪平于栈.西风何限,自起披衣看. 对此茫茫,不觉成长叹.何时旦,晓星欲散,飞起平沙雁. 在某个Python程序中看到这么一行 from unittest import mock 看起来 ...

  8. python 列表越界

    data = [1,8,5,9,7,4,5] print(data[10:]) #返回空 print(data[10]) #出错,越界

  9. Pyhton表白代码——浪漫圣诞节

    圣诞节即将到了,所以这回通过turtle模块来编写一个表白的小程序 开发时间:2019-12-15 开发工具:Sublime 开发模块:turtle 这里用到了turtle库的相关知识,如果不熟悉可以 ...

  10. C++使用libcurl做HttpClient 和 curl_easy_setopt

    curl_easy_setopt 参数设置 https://curl.haxx.se/libcurl/c/curl_easy_setopt.html  使用libcurl做HttpClient #if ...