引言

Lifecycle 是官方提供的架构组件之一,目前已经是稳定版本,Lifecycle 组件包括LifecycleOwner、LifecycleObserver。Lifecycle 组件是执行操作以响应另一个组件(Activity或者Fragment)的生命周期状态的更改。 Lifecycle 生成更易于组织、更轻量级,更易于维护的代码。

不使用Lifecycle

在使用MVP模式中,如果需要Presenter感知Activity或者Fragment的生命周期,传统做法是Presenter中定义多个和Activity或者Fragment相应的生命周期方法,然后在Activity或者Fragment中调用Presenter中定义的方法,例如:

class UserPresenter(view: IUserView) {
private val mView = view
private val mModel: UserModel = UserModel() fun onStart(){
// 初始化一些信息
} fun onDestroy(){
// 释放一起请求
}
}
class MainActivity : AppCompatActivity(), IUserView { private val userPresenter = UserPresenter(this) override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
} } override fun onStart() {
super.onStart()
userPresenter.onStart()
} override fun onDestroy() {
super.onDestroy()
userPresenter.onDestroy()
} override fun onLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
} override fun onSuccess() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
} override fun onComplete() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}

实际项目中,需求可能比较复杂,这样会导致太多类似的调用,而使onStart()和onDestroy() 方法变的非常臃肿。

使用Lifecycle

定义IPresenter 接口类,继承LifecycleObserver ,其它具体的Presenter继承该类,方便使用。

interface IPresenter : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart(owner: LifecycleOwner) @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy(owner: LifecycleOwner)
}

定义一个具体的UserPresenter,继承IPresenter

class UserPresenter(view: IUserView) : IPresenter {
private val mView = view
private val mModel: UserModel = UserModel() companion object {
const val TAG: String = "UserPresenter"
} override fun onStart(owner: LifecycleOwner) {
Log.d(TAG,"onStart and Presenter")
} override fun onDestroy(owner: LifecycleOwner) {
Log.d(TAG,"onDestroy and Presenter")
}
}

在Activity或者Fragment使用

class MainActivity : AppCompatActivity(), IUserView {

    companion object {
val TAG: String = "MainActivity"
} private val userPresenter = UserPresenter(this) override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
lifecycle.addObserver(userPresenter)// 订阅事件
} override fun onStart() {
super.onStart()
Log.d(TAG,"onStart and UI")
} override fun onDestroy() {
super.onDestroy()
Log.d(TAG,"onDestroy and UI")
} override fun onLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
} override fun onSuccess() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
} override fun onComplete() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}

运行查看下日志

2018-12-15 12:39:50.715 2679-2679/com.fomin.arch D/MainActivity: onStart and UI
2018-12-15 12:39:50.715 2679-2679/com.fomin.arch D/UserPresenter: onStart and Presenter
2018-12-15 12:39:53.876 2679-2679/com.fomin.arch D/UserPresenter: onDestroy and Presenter
2018-12-15 12:39:53.877 2679-2679/com.fomin.arch D/MainActivity: onDestroy and UI

这样Presenter 感知Activity或Fragment的生命周期已经实现,在Activity或Fragment生命周期变化会及时通知到Presenter。无需再Activity或Fragment实现相关Presenter的生命周期感知事件,减少维护成本。

Lifecycle原理

首先了解下Lifecycle组件主要有下面一些关键类

  • LifecycleObserver :实现该接口的类,通过注解的方式,可以通过被LifecycleOwner类的addObserver方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件
  • LifecycleOwner:实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件
  • Event:从框架和Lifecycle类派发的生命周期事件
  • State :由Lifecycle对象跟踪的组件的当前状态
  • LifecycleRegistry:负责控制state的转换、接受分发event事件

已Activity为例,会发现在SupportActivity里面继承了LifecycleOwner,持有LifecycleRegistry类,并且在getLifecycle()返回LifecycleRegistry类,方便继承类使用该类。

@RestrictTo(LIBRARY_GROUP)
public class SupportActivity extends Activity implements LifecycleOwner { private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @Override
@SuppressWarnings("RestrictedApi")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
} @CallSuper
@Override
protected void onSaveInstanceState(Bundle outState) {
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
super.onSaveInstanceState(outState);
} @Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}

而在业务Activity中需要lifecycle.addObserver(LifecycleObserver)订阅事件,这样就可以生效订阅/通知事件。Event分发是通过哪里进行分发的呢?可以看下ReportFragment.injectIfNeededIn(this)这句代码,ReportFragment对各个状态使用dispatch进行事件分发,然后调用LifecycleRegistry.handleLifecycleEvent,其接受到分发的Event从而改变State。

ReportFragment代码片段
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
(Lifecycle.Event.ON_CREATE);
} @Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
} @Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
} @Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
} @Override
public void onStop() {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
} @Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
// just want to be sure that we won't leak reference to an activity
mProcessListener = null;
} private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
} if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
} LifecycleRegistry代码片段
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
} private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
// happens only on the top of stack (never in reentrance),
// so it doesn't have to take in account parents
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
+ "new events from it.");
return;
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}

可以看下官方的对整个生命周期流动的解释

在该Lifecycle组件中,与传统的生命周期不同,只定义了五种状态,分别是:

  • INITIALIZED 最初始的状态
  • DESTROYED
  • CREATED
  • STARTED
  • RESUMED

上图中向右的箭头很好理解,每过来一个event会发生生命周期状态的变更,向左的箭头可以看成状态的回滚, 如果在RESUMED状态发生了ON_PAUSE事件,则状态回滚到STARTED状态;STARTED状态发生了ON_STOP事件,则回滚到CREATED状态。

总结

需要注意了是,在继承LifecycleObserver 时,官方建议使用DefaultLifecycleObserver ,因为随着Java8成为主流,将不会再使用注解方式,DefaultLifecycleObserver是需要另外声明的java8,并且最低API24才能build success。而GenericLifecycleObserver,FullLifecycleObserver,DefaultLifecycleObserver 这三个接口都是直接或者间接继承的LifecycleObserver。

// java8的lifecycle引用
implementation "android.arch.lifecycle:common-java8:1.1.1"
// 注解方式lifecycle引用
implementation 'android.arch.lifecycle:extensions:1.1.1'

Lifecycle使用,保持 UI 控制器(Activity 和 Fragment)尽可能的精简,更易复用,同时和LiveDataViewModel等使用更具有最佳实战。

Android Lifecycle使用的更多相关文章

  1. Android lifecycle 使用详解

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...

  2. Android lifecycle 实战及使用进阶

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...

  3. 转 Android Lifecycle、ViewModel和LiveData

    转自:https://www.jianshu.com/p/982545e01d0a 1.概述 在I / O '17的时候,其中一个重要的主题是Architecture Components.这是一个官 ...

  4. Android Platform Guide

    This guide shows how to set up your SDK environment to deploy Cordova apps for Android devices, and ...

  5. Android 中的MVC与数据流动

    今天看了一个Android的Training生命周期转换的例子,顿觉得他的设计非常巧妙,我的分析如下: 1.在com.example.android.lifecycle包中有: 3个正常的全屏acti ...

  6. Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础

    原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...

  7. Jetpack 架构组件 Lifecycle 生命周期 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. Android程序员必备精品资源

    平时写程序中不断收集到的一些比较常用的东西,分享给大家. 实用工具集锦 Android Lifecycle https://github.com/xxv/android-lifecycle TinyP ...

  9. Android lifecyle 源码解剖 - gdutxiaoxu的博客(微信公众号 stormjun94)

    版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...

随机推荐

  1. 在ASP.NET MVC里对Web Page网页进行权限控制

    我们在ASP.NET MVC开发时,有时候还是得设计ASP.NET的Web Page网页(.aspx和.aspx.cs),来实现一些ASP.NET MVC无法实现的功能,如此篇<Visual S ...

  2. HBase体系架构和集群安装

    大家好,今天分享的是HBase体系架构和HBase集群安装.承接上两篇文章<HBase简介>和<HBase数据模型>,点击回顾这2篇文章,有助于更好地理解本文. 一.HBase ...

  3. ECDSA数字签名算法

    一.ECDSA概述 椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟.ECDSA于1999年成为ANSI标准,并于2000年成为IEEE和NIST标准.它在 ...

  4. Android Studio 调试各种国产手机经验总结

    为何加上“国产”二字呢,因为目前测试时就国产手机存在的安装问题多,而且都很奇葩,不得不说对于开发者时很不友好的. 下面就是个人总结的针对不同的机型调试时出现的问题做的总结: 1.VIVO 手机 解决方 ...

  5. Javascript高级编程学习笔记(40)—— DOM(6)CDATASection、DocumentType

    CDATASection类型 CDATASection类型是只针对XML文档的类型 因为浏览器无法解析 在浏览器中创建CDATASection的函数也无法正常使用 该类型有以下属性 nodeType: ...

  6. 微信小程序消息通知-打卡考勤

    微信小程序消息通知-打卡考勤 效果: 稍微改一下js就行,有不必要的错误,我就不改了,哈哈! index.js //index.js const app = getApp() // 填写微信小程序ap ...

  7. 在谷歌安装扩展程序Axure RP Extension for Chrome后,经常无故损坏,无法使用

    最近因为要看需求给的原型图,但需求只给了html格式的文件,没有给可以在Axure软件里看的格式, 所以在谷歌安装了一个Axure RP Extension for Chrome扩展程序在谷歌浏览器看 ...

  8. SpringMvc + socket.io + vue + vue-socket.io实例

    SpringMvc部分实现  1. 所需依赖 <dependency>           <groupId>com.corundumstudio.socketio</g ...

  9. python基础-列表(7)

    一.列表格式 列表名 = [列表元素1,列表元素2,列表元素3,… ] 说明: 列表元素之间是有顺序的,也是通过下标表示,第一个元素的小标为0. 列表元素可以不是同种类型,任何类型都行 列表通常当做容 ...

  10. sql中base64解码、译码

    1.5.6版本及之后的版本的base64 主要就是两个MySQL内部函数to_base64和from_base64,使用也很简单,如下: 1)先查看MySQL的版本:mysql> select ...