Android lifecycle 使用详解
版权声明:本文为博主原创文章,遵循CC 4.0
by-sa版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gdutxiaoxu/article/details/86660746
说在前面
本次推出 Android Architecture Components 系列文章,目前写好了四篇,主要是关于 lifecycle,livedata
的使用和源码分析,其余的 Navigation, Paging library,Room,WorkMannager
等春节结束之后会更新,欢迎关注我的公众号,有更新的话会第一时间会在公众号上面通知。
github sample 地址:
ArchiteComponentsSample
Android 技术人,一位不羁的码农。

简介
lifecycle 是 2107 年 google 大会推出来的,它属于 architecture compoment 里面的一个组件,它可以干什么用呢?
简单得来说,它可以用来检查 Activity 的生命周期,而不必强依赖 Activity。
为什么要引进 lifecycle
举一下我们最常用的 MVP 例子,没引进 lifecycle 之前,我们需要在 Activity 或者 Fragment 销毁的时候,即 onDestroy
的时候手动调用 onDestroy 方法,这里会带来一些问题,每一次在 Activity 或者 Fragment 销毁的烧开后都要调用
presenter.destory() 方法,这样的代码枯燥,毫无意义。
class MyPresenter{
public MyPresenter() {
}
void create() {
//do something
}
void destroy() {
//do something
}
}
class MyActivity extends AppCompatActivity {
private MyPresenter presenter;
public void onCreate(...) {
presenter= new MyPresenter ();
presenter.create();
}
public void onDestroy() {
super.onDestroy();
presenter.destory();
}
}
当然我们也可以定义一些 IBasePresenter 的接口,在 BaseActivity 的时候调用 IBasePresenter 的 onDestroy
方法,这样也确实能做到。只不过稍微繁琐一点。
那如果是别的类的呢,比如 MediaCompoment,在 Activity 的时候,我们需要销毁一些资源,按照传统的方法,我们还是需要在 Activity
onDestroy 的时候手动调用 onDestroy 方法。那有没有更好的方法呢?当然是有的,lifecycle
就可以解决这个问题。接下来,我们先来看一下 Lifycycle 的基本使用。
Lifycycle 的基本使用
- 引入相关的依赖包
Lifecycle 已经是稳定版,它包含在 support library 26.1.0
及之后的依赖包中,如果我们的项目基于这些依赖包,那么不需要额外的引用。
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:1.1.0"
// alternatively, just ViewModel
implementation "android.arch.lifecycle:viewmodel:1.1.0"
// alternatively, just LiveData
implementation "android.arch.lifecycle:livedata:1.1.0"
support library在26.1.0 之前,lifecycle 并没有集成进去,需要我们引入另外的包。
implementation "android.arch.lifecycle:extensions:1.0.0-alpha4"
- 使用
这里同样分为几种情况
- support library 26.1.0 之后,且继承 FragmentActivity,那么我们直接调用 getLifecycle().addObserver 方法即可,当 Activity 的生命周期变化的时候,将会回调 onStateChanged 的方法,状态分别是一一对应的
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 GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
Log.d(TAG, "onStateChanged: event =" + event);
}
});
}
}
- support library 26.1.0 之后,不是继承 FragmentActivity,只是简单地继承 Actiivty
public class SimpleLifecycleActivity extends Activity implements LifecycleOwner {
private static final String TAG = "SimpleLifecycleActivity";
private LifecycleRegistry mLifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_lifecycle);
mLifecycleRegistry = new LifecycleRegistry(this);
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
Log.d(TAG, "onStateChanged: event =" + event);
}
});
}
@Override
protected void onStart() {
super.onStart();
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
- support library 26.1.0 之前
(现在的 support library 基本都在 26.1.0 之后了,这个可以忽略)
第一步:实现 LifecycleOwner 接口,并返回响应的 Lifecycle
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
第二步:在 Activity 生命周期变化的时候,调用 mLifecycleRegistry.handleLifecycleEvent
方法,分发相应的生命周期。
第三步:调用 Lifecycle 的 addObserver 方法添加相应的 Observer。
代码如下
public class MainActivity extends AppCompatActivity implements LifecycleOwner {
private LifecycleRegistry mRegistry;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRegistry = new LifecycleRegistry(this);
mRegistry.markState(Lifecycle.State.CREATED);
getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
Log.d(TAG, "onStateChanged:event =" + event);
}
@Override
public Object getReceiver() {
return null;
}
});
}
@Override
protected void onStart() {
super.onStart();
mRegistry.markState(Lifecycle.State.STARTED);
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
@Override
protected void onResume() {
super.onResume();
mRegistry.markState(Lifecycle.State.RESUMED);
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
@Override
protected void onPause() {
super.onPause();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
@Override
protected void onStop() {
super.onStop();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
@Override
protected void onDestroy() {
super.onDestroy();
mRegistry.markState(Lifecycle.State.DESTROYED);
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
@Override
public Lifecycle getLifecycle() {
return mRegistry;
}
}
总结
我们回过头来看一下我们上面提出的问题?
MediaCompoment 在 Activity ondestroy 的时候,我们需要销毁一些资源,用传统的方法,我们需要在 Activity
onDestroy 的时候手动调用 onDestroy 方法。这样会存在一个问题,调用者必须知道比较清楚得知道 MediaCompoment
的设计,否则可能会忘记调用 onDestroy 的方法。
那有没有一种方法, 当 Activity 生命周期变化的时候,MediaCompoment 自身能够检测到 Activity 的
生命周期变化,从而做相应的处理。
答案当然是有的,使用 lifycycle。
public class MediaCompoment {
private static final String TAG = "MediaCompoment";
private final LifecycleOwner mLifecycleOwner;
public MediaCompoment(LifecycleOwner lifecycleOwner) {
mLifecycleOwner = lifecycleOwner;
mLifecycleOwner.getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, final Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_CREATE) {
onCreate();
} else if (event == Lifecycle.Event.ON_START) {
onStart();
} else if (event == Lifecycle.Event.ON_RESUME) {
onResume();
} else if (event == Lifecycle.Event.ON_PAUSE) {
onPause();
} else if (event == Lifecycle.Event.ON_STOP) {
onStop();
} else if (event == Lifecycle.Event.ON_DESTROY) {
onDestroy();
}
}
});
}
public void onCreate() {
Log.d(TAG, "onCreate:");
}
public void onStart() {
Log.d(TAG, "onStart:");
}
public void onResume() {
Log.d(TAG, "onResume:");
}
public void onPause() {
Log.d(TAG, "onPause:");
}
public void onStop() {
Log.d(TAG, "onStop:");
}
public void onDestroy() {
Log.d(TAG, "onDestroy:");
}
}
小结:
- lifycycle 其实是用观察者模式实现的,当 Activity 生命周期变化的时候,通知相应的 Observers 即观察者。
- 使用 lifecycle,我们可以将释放资源的动作内聚在自身,减少与调用者之间的耦合。
下一篇博客:Android LiveData
使用详解
Android lifecycle 使用详解的更多相关文章
- android:ToolBar详解
android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...
- Android之canvas详解
首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, y ...
- 【转】Android Canvas绘图详解(图文)
转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...
- Android 核心分析 之八Android 启动过程详解
Android 启动过程详解 Android从Linux系统启动有4个步骤: (1) init进程启动 (2) Native服务启动 (3) System Server,Android服务启动 (4) ...
- Android GLSurfaceView用法详解(二)
输入如何处理 若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...
- Android编译过程详解(一)
Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...
- android屏幕适配详解
android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...
- Android.mk文件详解(转)
源:Android.mk文件详解 从对Makefile一无所知开始,折腾了一个多星期,终于对Android.mk有了一个全面些的了解.了解了标准的Makefile后,发现Android.mk其实是把真 ...
- Android Studio 插件开发详解四:填坑
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78265540 本文出自[赵彦军的博客] 在前面我介绍了插件开发的基本流程 [And ...
随机推荐
- Redis+Twemproxy分片存储实现
from unsplash 为提高Redis存储能力的提升,以及对外提供服务可用性提升,有时候有必要针对Redis进行集群式搭建,比较常用的有Twemproxy分片存储以及官方提供的Cluster方式 ...
- Java学习笔记之---集合
Java学习笔记之---集合 (一)集合框架的体系结构 (二)List(列表) (1)特性 1.List中的元素是有序并且可以重复的,成为序列 2.List可以精确的控制每个元素的插入位置,并且可以删 ...
- android_activity_研究(一)
android中活动的概念(activity)是一个很重要的东东.这里有很多东东值得好好研究.最好的研究来源当然是官网啦,所以本人这里写一点对官网文章的研究心得. 一.活动(activity)的概念 ...
- 7月18日刷题记录 二分答案跳石头游戏Getting
通过数:1 明天就要暑假编程集训啦~莫名开心 今天做出了一道 二分答案题(好艰辛鸭) 1049: B13-二分-跳石头游戏(二分答案) 时间限制: 5 Sec 内存限制: 256 MB提交: 30 ...
- stack用法,queue用法,
stack stack 模板类的定义在头文件中. stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要 的,在不指定容器类型时,默认的容器类型为deque. 定义st ...
- 个人永久性免费-Excel催化剂功能第96波-地图数据挖宝之全国天气查询(区域最细可到区县,最长预报4天)
天气预报的信息,是很普通的大家习以为常的信息,但如果不进行采集,在日常数据分析过程中,就少了非常重要的一个分析维度,如果人手采集整理,工作量巨大.此篇给广大数据分析工作者再次减负,只需简单一键,即可批 ...
- Spring Boot 中 Redis 的使用
Spring Boot 对常用的数据库支持外,对 Nosql 数据库也进行了封装自动化,如Redis.MongoDB等,本文主要介绍Redis的使用. Redis 介绍 Redis 是目前业界使用最广 ...
- Python3安装与使用urllib2包之小坑
Python3 安装urllib2包之小坑 Python3.6.6或者说python3.x找不到urllib2语法问题修改之后,会报一个没有安装urllib2的包的错误. 通过pip install ...
- python面向过程编程小程序- 模拟超市收银系统
6.16自我总结 功能介绍 程序功能介绍: 商品信息再读取修改买卖均已xlsx格式 且生成购物记录也按/用户名/购买时间.xlsx格式生成 账号密码输入错误三次按照时间进行冻结 用户信息已json格式 ...
- 手把手教你破解文件密码、wifi密码、网页密码
手把手教你破解文件密码.wifi密码.网页密码 1.破解文件密码: 有时候我们在网上下载一个压缩包后,必须要关注或者支付一定费用才给你解压密码,实属比较恶心.在这里手把手叫你实现破解文件解压密码. 1 ...