您的位置:首页 > 运维架构 > 网站架构

Android架构组件—Lifecycle

2018-03-02 10:17 507 查看

概述

Lifecycle组件是LiveData和ViewModle的基础,包括LifecycleOwner、LifecycleObserver。所以先学习Lifecycle有助于后续理解架构组件。

为什么需要Lifecycle?

在我们日常编码过程中,不可避免要和activity、fragment这些系统控制生命周期的组件打交道,在添加一系列功能的同时和这些组件生命周期绑定是完成一个优秀app的基础。比如说MVP模式中的Presenter需要感知Activity或者Fragment的生命周期?以前可能会这样做:Presenter中定义多个和Activity或者Fragment相应的生命周期方法,然后在Activity或者Fragment中调用Presenter中定义的方法。

定义一个符合activity生命周期的接口:

public interface IPresenter {
void onCreate();

void onStart();

void onResume();

void onPause();

void onStop();

void onDestroy();
}


创建一个实现该接口的Presenter:

public class MainPresenter implements IPresenter {

public MainPresenter(Context context){

}

@Override
public void onCreate() {

}

@Override
public void onStart() {

}

@Override
public void onResume() {

}

@Override
public void onPause() {

}

@Override
public void onStop() {

}

@Override
public void onDestroy() {

}
}


在activity生命周期中调用Presenter中的方法:

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private IPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: ");
setContentView(R.layout.activity_main);
mPresente
1125c
r = new MainPresenter(this);
mPresenter.onCreate();
}

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

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

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

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

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


注意:上面的这种Presenter持有activity的context引用,在activity已经destroy后可能会引起内存泄漏

上面的这种例子通俗易懂,实际生产环境中 ,这样的代码会非常复杂,最终会有太多的类似调用并且会导致 onCreate() 和 onDestroy() 方法变的非常臃肿。所以架构组件中的Lifecycle就是为了解决这种问题

添加Lifecycle依赖

在project的gradle文件中添加google的maven仓库:

buildscript {
repositories {
google()
jcenter()
}
}


在module的gradle文件中添加Lifecycle包:

//For Lifecycles, LiveData, and ViewModel
compile "android.arch.lifecycle:runtime:1.0.0-alpha1"
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"


怎么使用Lifecycle?

还是上面的那种需要,来看看使用Lifecycle后怎么实现:

定义一个接口继承LifecycleObserver:

public interface IPresenter extends LifecycleObserver {

@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreate(@NotNull LifecycleOwner owner);

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void onDestroy(@NotNull LifecycleOwner owner);

@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onLifecycleChanged(@NotNull LifecycleOwner owner,
@NotNull Lifecycle.Event event);
}


定义一个Prsenter实现上述接口:

public class MainPresenter implements IPresenter {

private static final String TAG = "MainPresenter";

@Override
public void onLifecycleChanged(@NotNull LifecycleOwner owner, @NotNull Lifecycle.Event event) {

}

@Override
public void onCreate(@NotNull LifecycleOwner owner) {
Log.d("tag", "MainPresenter.onCreate" + this.getClass().toString());
}

@Override
public void onDestroy(@NotNull LifecycleOwner owner) {
Log.d("tag", "MainPresenter.onDestroy" + this.getClass().toString());
}
}


在activity的生命周期中添加Presenter观察者:

public class MainActivity extends AppCompatActivity {
private IPresenter mPresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("tag", "onCreate" + this.getClass().toString());
setContentView(R.layout.activity_main);
mPresenter = new MainPresenter(this);
getLifecycle().addObserver(mPresenter);//添加LifecycleObserver
}

@Override
protected void onDestroy() {
Log.d("tag", "onDestroy" + this.getClass().toString());
super.onDestroy();
}
}


如此,每当Activity发生了对应的生命周期改变,Presenter就会执行对应事件注解的方法:

除onCreate和onDestroy事件之外,Lifecycle一共提供了所有的生命周期事件,只要

通过注解进行声明,就能够使LifecycleObserver观察到对应的生命周期事件:

public enum Event {
/**
* Constant for onCreate event of the {@link LifecycleOwner}.
*/
ON_CREATE,
/**
* Constant for onStart event of the {@link LifecycleOwner}.
*/
ON_START,
/**
* Constant for onResume event of the {@link LifecycleOwner}.
*/
ON_RESUME,
/**
* Constant for onPause event of the {@link LifecycleOwner}.
*/
ON_PAUSE,
/**
* Constant for onStop event of the {@link LifecycleOwner}.
*/
ON_STOP,
/**
* Constant for onDestroy event of the {@link LifecycleOwner}.
*/
ON_DESTROY,
/**
* An {@link Event Event} constant that can be used to match all events.
*/
ON_ANY
}


Lifecycle组件原理

借鉴Android 架构组件(一)——Lifecycle的一张图进行简单的概括:



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

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

Lifecycle(生命周期):和LifecycleOwner不同的是,LifecycleOwner本身持有Lifecycle对象,LifecycleOwner通过其Lifecycle getLifecycle()的接口获取内部Lifecycle对象。

State(当前生命周期所处状态):如图所示。

Event(当前生命周期改变对应的事件):如图所示,当Lifecycle发生改变,如进入onCreate,会自动发出ON_CREATE事件。

以V4包中的Fragment(AppCompatActivity类似)为例,看下Fragment和LifecycleOwner、LifecycleObserver、Lifecycle之间的类关系图。

Lifecycle组件成员Lifecycle被定义成了抽象类,LifecycleOwner、LifecycleObserver被定义成了接口;

Fragment实现了LifecycleOwner接口,该只有一个返回Lifecycle对象的方法getLifecyle();

Fragment中getLifecycle()方法返回的是继承了抽象类Lifecycle的LifecycleRegistry。

LifecycleRegistry中定义嵌套类ObserverWithState,该类持有GenericLifecycleObserver对象,而GenericLifecycleObserver是继承了LifecycleObserver的接口。

public class Fragment implements xxx, LifecycleOwner {

//...省略其他

LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}

public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}


实现了getLifecycle()方法返回 LifecycleRegistry 对象,LifecycleRegistry对象继承了 Lifecycle。在Fragment对应的生命周期内,都会发送对应的生命周期事件给内部的 LifecycleRegistry对象处理:

public class Fragment implements xxx, LifecycleOwner {
//...
void performCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState);  //1.先执行生命周期方法
//...省略代码
//2.生命周期事件分发
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

void performStart() {
onStart();
//...
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}

void performResume() {
onResume();
//...
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}

void performPause() {
//3.注意,调用顺序变了
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
//...
onPause();
}

void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
//...
onStop();
}

void performDestroy() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
//...
onDestroy();
}
}


参照Android 架构组件(一)——Lifecycle文中的时序图:



在Fragment(AppCompatActivity也一样)中调用getLifecycle()方法得到LifecycleRegistry对象,然后调用addObserver()方法并将实现了LifecycleObserver接口的对象作为参数传进去。这样一个过程就完成了注册监听的过程。

后续就是Fragment生命周期变化时,通知LifecycleObserver的过程:Fragment的performXXX()、onXXX()方法;LifecycleRegistry的handleLifecycleEvent()方法;LifecycleObserver的onXXX()方法。

Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法 ,然后调用自身的onXXX()方法,可以通过打印log验证。

LifecycleRegistry

LifecycleRegistry 就是 Lifecycle 的子类:

public class LifecycleRegistry extends Lifecycle {
}


Lifecycle 类:

public abstract class Lifecycle {

//注册LifecycleObserver (比如Presenter)
public abstract void addObserver(@NonNull LifecycleObserver observer);
//移除LifecycleObserver
public abstract void removeObserver(@NonNull LifecycleObserver observer);
//获取当前状态
public abstract State getCurrentState();

public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}

public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;

public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}


作为Lifecycle的子类,LifecycleRegistry 同样也能通过addObserver方法注册LifecycleObserver ,当LifecycleRegistry 本身的生命周期改变后(内部一定有一个成员变量State记录当前的生命周期),LifecycleRegistry 就会通过handleLifecycleEvent()逐个通知每一个注册的LifecycleObserver ,并执行对应生命周期的方法。

addObserver()方法:

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}

boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}

if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}


LifecycleRegistry的handleLifecycleEvent()相关的方法:

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(); //看下sync()方法的具体实现
mHandlingEvent = false;
}

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.
//比较当前的生命周期和Map中第一个的观察者的生命周期,下面的另一个if语句类似。
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;
}

//看下forwardPass()方法

private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
popParentState();
}
}
}

static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;

ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}

void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event); //通知观察者生命周期变化。
mState = newState;
}
}


Tips

1、尝试复用LifecycleRegistry

首先,LifecycleRegistry 本身就是一个成熟的 Lifecycle 实现类,它被实例化在Activity和Fragment中使用,如果我们需要自定义LifecycleOwner 并实现接口需要返回一个Lifecycle实例,完全可以直接在自定义LifecycleOwner中new一个LifecycleRegistry成员并返回它(简而言之就是:直接拿来用即可)。

以下是Google官方文档:

LifecycleRegistry: An implementation of Lifecycle that can handle multiple observers. It is used by Fragments and Support Library Activities. You can also directly use it if you have a custom LifecycleOwner.

2、注解和DefaultLifecycleObserver的取舍

其次,Google的Lifecycle库中提供了一个 DefaultLifecycleObserver 类,方便我们直接实现LifecycleObserver接口,相比较于文中demo所使用的注解方式,Google官方更推荐我们使用 DefaultLifecycleObserver 类,并声明

一旦Java 8成为Android的主流,注释将被弃用,所以介于DefaultLifecycleObserver和注解两者之间,更推荐使用 DefaultLifecycleObserver 。

官方原文:

/*
* If you use <b>Java 8 Language</b>, then observe events with {@link DefaultLifecycleObserver}.
* To include it you should add {@code "android.arch.lifecycle:common-java8:<version>"} to your
* build.gradle file.
* <pre>
* class TestObserver implements DefaultLifecycleObserver {
*     {@literal @}Override
*     public void onCreate(LifecycleOwner owner) {
*         // your code
*     }
* }
* </pre>
* If you use <b>Java 7 Language</b>, Lifecycle events are observed using annotations.
* Once Java 8 Language becomes mainstream on Android, annotations will be deprecated, so between
* {@link DefaultLifecycleObserver} and annotations,
* you must always prefer {@code DefaultLifecycleObserver}.
*/


3、Lifecycles 的最佳实践

本小节内容节选自《[译] Architecture Components 之 Handling Lifecycles》

作者:zly394

链接:https://juejin.im/post/5937e1c8570c35005b7b262a

保持 UI 控制器(Activity 和 Fragment)尽可能的精简。它们不应该试图去获取它们所需的数据;相反,要用 ViewModel来获取,并且观察 LiveData将数据变化反映到视图中。

尝试编写数据驱动(data-driven)的 UI,即 UI 控制器的责任是在数据改变时更新视图或者将用户的操作通知给 ViewModel。

将数据逻辑放到 ViewModel 类中。ViewModel 应该作为 UI 控制器和应用程序其它部分的连接服务。注意:不是由 ViewModel 负责获取数据(例如:从网络获取)。相反,ViewModel 调用相应的组件获取数据,然后将数据获取结果提供给 UI 控制器。

使用Data Binding来保持视图和 UI 控制器之间的接口干净。这样可以让视图更具声明性,并且尽可能减少在 Activity 和 Fragment 中编写更新代码。如果你喜欢在 Java 中执行该操作,请使用像Butter Knife 这样的库来避免使用样板代码并进行更好的抽象化。

如果 UI 很复杂,可以考虑创建一个 Presenter 类来处理 UI 的修改。虽然通常这样做不是必要的,但可能会让 UI 更容易测试。

不要在 ViewModel 中引用View或者 Activity的 context。因为如果ViewModel存活的比 Activity 时间长(在配置更改的情况下),Activity 将会被泄漏并且无法被正确的回收。

总结

虽然以前Rxlifecycle这类也可以解决这类问题,但既然官方推出并在源码集成了,没理由多依赖一层,所以Lifecycle还是有可取之处的。相对于其它架构组件之间的配合,Lifecycle更简单且独立。

源码分析:

Lifecycle-aware Components 源码分析 @chaosleong
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: