<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont

本文涉及的产品
转发路由器TR,750小时连接 100GB跨地域
简介: 综述对于Activity和Fragment的生命周期都不会陌生,同样在我们自己的项目中也会需要做一需要依赖Activity和Fragment生命周期的操作。

综述

对于Activity和Fragment的生命周期都不会陌生,同样在我们自己的项目中也会需要做一需要依赖Activity和Fragment生命周期的操作。例如在onSaveInstanceState执行后不可在对Fragment进行操作,又比如我们需要在Activity的onDestroy中做一些释放的操作避免内存泄漏的情况出现。通常我们大多数的业务逻辑都不会写在Activity或者我们的Fragment当中。这时候便需要写一系列的方法以便在Activity中调用。当业务逻辑复杂起来,所依赖的类逐渐变多,层次加深以后,这些操作尤其显得十分繁琐。很庆幸google给我们Android Architecture Components中Lifecycles可以解决这一问题。

Lifecycles使用

如何添加Lifecycles的依赖在这里就不再说明,直接在官网查看最新依赖即可。对于Lifecycles的使用非常的简单。在这里我们就以MVP模式为例,在P层中如果想在Activity或者Fragment的onCreate和onDestroy中对Presenter做一些初始化和释放的的操作,通常情况下会在P层写一个初始化和释放的方法并且在Activity中的onCreate和onDestroy中进行调用。现在通过Lifecycles来实现就简单的多了。下面通过代码来看一下Lifecycles的使用,在这里创建了一个MainActivity和其对应的Presenter。

创建一个MainActivity类

public class MainActivity extends AppCompatActivity implements LifecycleRegistryOwner {

    private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
    private MainPresenter presenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new MainPresenter();
        getLifecycle().addObserver(presenter);
    }

    @Override
    public LifecycleRegistry getLifecycle() {
        return mRegistry;
    }

}

创建一个MainPresenter,在这里仅仅只是打印出部分生命周期的调用日志

public class MainPresenter implements LifecycleObserver{

    private static final String TAG = MainPresenter.class.getSimpleName();

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void onCreate(){
        Log.e(TAG,"onCreate");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume(){
        Log.e(TAG,"onResume");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause(){
        Log.e(TAG,"onPause");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy(){
        Log.e(TAG,"onDestroy");
    }
}

通过上面代码可以看出Lifecycles的使用是非常的简单。对首先在Activity或者Fragment中实现LifecycleRegistryOwner接口,当然也可以继承LifecycleActivity或者LifecycleFragment。在这里建议采用通过实现LifecycleRegistryOwner接口的方式。然后在创建的MainPresenter中实现LifecycleObserver接口,并且通过OnLifecycleEvent来指定相对应Activity生命周期的方法。最后在Activity中注册这个Presenter即可。下面来看一下运行结果。
这里写图片描述
注意:这里是用的Fragment实现LifecycleRegistryOwner接口时必须使用Support的Fragment而不是原生的Fragment,而对应的Activity也应该是FragmentActivity。 原因稍后说明。

Lifecycles源码分析

以下是基于1.0.0-alpha9版本的源码进行分析。对于Lifecycles这个lib来说,我们会有很多个类需要监听Activity或者Fragment的生命周期,当Activity或者Fragment的生命周期发生改变的时候会通知这些类来执行相对应的方法。从这里很容易看出,它实际上就是一个典型的观察着模式
Lifecycles是会在应用启动的时候通过一个ContentProvider完成初始化注册。可以看到在AndroidManifest.xml中注册了一个provider。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.arch.lifecycle.extensions"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="26" />

    <application>
        <provider
            android:name="android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
            android:authorities="${applicationId}.lifecycle-trojan"
            android:exported="false"
            android:multiprocess="true" />
    </application>

</manifest>

可以在下面路径找到这个AndroidManifest。

/build/intermediates/exploded-aar/android.arch.lifecycle/extensions/1.0.0-alpha3/AndroidManifest.xml

找到LifecycleRuntimeTrojanProvider这个类,可以看到在这里对LifecycleDispatcher进行初始化操作,在应用启动的时候会对它进行初始化,其余的都是一些ContentProvider的默认配置。

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class LifecycleRuntimeTrojanProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        LifecycleDispatcher.init(getContext());
        ProcessLifecycleOwner.init(getContext());
        return true;
    }
    ......

从LifecycleDispatcher这个类的名字可以看出,他是对生命周期的事件进行分发处理的。
在这里看一下LifecycleDispatcher中初始化的方法。

static void init(Context context) {
    if (sInitialized.getAndSet(true)) {
        return;
    }
    ((Application) context.getApplicationContext())
            .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}

在LifecycleDispatcher的初始化过程中,会在应用的Application中注册Activity生命周期的回调。DispatcherActivityCallback是LifecycleDispatcher中的一个内部类,下面在看一下这个类。

static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
    private final FragmentCallback mFragmentCallback;

    DispatcherActivityCallback() {
        mFragmentCallback = new FragmentCallback();
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        if (activity instanceof FragmentActivity) {
            ((FragmentActivity) activity).getSupportFragmentManager()
                    .registerFragmentLifecycleCallbacks(mFragmentCallback, true);
        }
        ReportFragment.injectIfNeededIn(activity);
    }

    ......
}

在这个DispatcherActivityCallback中的核心代码是onActivityCreated方法,从这个方法里面做了两件事情,一是注册了Fragment的回调,二是创建了ReportFragment。其实这两件事情实际上就是对我们创建的Fragment和Activity的生命周期进行监听和事件分发。在这里分别来看一下是如何实现的。
1.监听Fragment的生命周期
在上面的第10~13行代码中,判断我们使用的Activity是FragmentActivity之后注册了Fragement生命周期的回调,同样FragmentCallback也是LifecycleDispatcher中的一个内部类。

@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static class FragmentCallback extends FragmentManager.FragmentLifecycleCallbacks {

    @Override
    public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) {
        dispatchIfLifecycleOwner(f, ON_CREATE);

        if (!(f instanceof LifecycleRegistryOwner)) {
            return;
        }

        if (f.getChildFragmentManager().findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            f.getChildFragmentManager().beginTransaction().add(new DestructionReportFragment(),
                    REPORT_FRAGMENT_TAG).commit();
        }
    }
    ......
}

在FragmentCallback中我们可以清晰的看到,如果我们创建的Fragment实现了LifecycleRegistryOwner接口,在其相应的生命周期中对ON_CREATE,ON_START,ON_RESUME事件进行分发。这里在Fragment生命周期的回调中仅仅只是对Fragment一些启动事件的分发处理,那么对于Fragment销毁事件的处理则是通过DestructionReportFragment。也就是在获取到我们创建的FragmentActivity之后去add一个DestructionReportFragment对象,在DestructionReportFragment中完成ON_PAUSE,ON_STOP,ON_DESTROY事件的分发处理。DestructionReportFragment代码不在贴出。这样以来就完成了对Fragment生命周期事件的分发。
在这里会有两个疑问,第一,为什么要通过DestructionReportFragment来处理Fragment销毁事件的分发,而不是完全通过Fragment生命周期的回调来处理?第二,从注册Fragment的回调开始一直使用的都是Support中的Fragment,也就是说对于Fragment的生命周期事件的分发获取只支持Support中的Fragment,不支持原生的Fragment,为什么要这么做?
首先来看一下第一个问题,在Fragemnt的回调接口中,onFragmentStarted,onFragmentResumed等会在我们创建的Fragment的onStart和onResumed之后执行,对于销毁的生命周期,通过DestructionReportFragment来执行事件分发,会在我们创建的Fragment中的onPause等执行之前完成事件分发。这样就能在我们创建的Fragment初始化完成之后完成响应的启动事件处理,在销毁之前完成响应销毁事件的处理。
对于第二个问题在Android原生的Fragment中并没有提供对Fragment的生命周期有着相应的回调接口,如果使用add一个Fragment方式来处理,就会使得所有的事件都会提前到我们创建的Fragment生命周期执行之前进行处理。所以目前只支持Support中的Fragment。
2.监听Activity的生命周期
对于Activity生命周期的监听处理就很简单了,他是通过ReportFragment来同步的.

public class ReportFragment extends Fragment {

    private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";

    public static void injectIfNeededIn(Activity activity) {
        // ProcessLifecycleOwner should always correctly work and some activities may not extend
        // FragmentActivity from support lib, so we use framework fragments for activities
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
    }

    ......

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(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;
    }

    ......
}

通过ReportFragment代码中可以看出是在Fragment相对应的生命周期中进行事件分发的。ReportFragment使用的是Android原生的Fragment,而不是Support中的Fragment,这样做的目的是为了兼容所有的Activity,使用Support中的Fragment的话只能适用于FragmentActivity了。使用ReportFragment的进行对相应的生命周期进行分发的好处就是不用直接依赖Activity生命周期的回调,讲这些事件交由Fragment处理,降低了对Activity的侵入性。
在对Fragment和Activity对应生命周期进行分发时,分别调用LifecycleDispatcher中的dispatchIfLifecycleOwner方法和ReportFragment中的dispatch方法。
LifecycleDispatcher中的dispatchIfLifecycleOwner方法:

private static void dispatchIfLifecycleOwner(Fragment fragment, Lifecycle.Event event) {
    if (fragment instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) fragment).getLifecycle().handleLifecycleEvent(event);
    }
}

ReportFragment中的dispatch方法:

private void dispatch(Lifecycle.Event event) {
    if (getActivity() instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) getActivity()).getLifecycle().handleLifecycleEvent(event);
    }
}

因为我们的Activity和Fragment实现了LifecycleRegistryOwner接口,所以在这里实际上调用的LifecycleRegistry的handleLifecycleEvent方法。

public void handleLifecycleEvent(Lifecycle.Event event) {
    mState = getStateAfter(event);
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        return;
    }
    mHandlingEvent = true;
    sync();
    mHandlingEvent = false;
}

这个方法的核心部分是调用sync方法。

private void sync() {
    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();
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass();
        }
    }
    mNewEventOccurred = false;
}

在这里会根据将当前实际生命周期的状态和观察者所持有的状态进行比较,之后会根据观察者所持有事件的状态完成对事件的分发,并同步之前和之后的事件。这个方法只会被处于栈顶的Activity调用。以backwardPass方法为例。

private void backwardPass() {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            Event event = downEvent(observer.mState);
            pushParentState(getStateAfter(event));
            observer.dispatchEvent(mLifecycleOwner, event);
            popParentState();
        }
    }
}

在这里可以看出是遍历mObserverMap来完成对所有观察者的分发,在每次注册一个observer的时候也就是调用LifecycleRegistry中addObserver的时候都会根据一个observer生成一个ObserverWithState对象,并保存在这个map对象中。对事件的处理也是调用ObserverWithState中的dispatchEvent方法。

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;
    }
}

在这里可以看出通过Lifecycling的getCallback方法来获取一个GenericLifecycleObserver对象,通过调用GenericLifecycleObserver的onStateChanged方法来完成对生命周期的事件分发。在对Lifecycles使用过程中,是通过注解来完成对相应生命周期方法的调用。例如在上面的demo中rebuild代码之后会生成如下代码。

public class MainPresenter_LifecycleAdapter implements GenericLifecycleObserver {
  final MainPresenter mReceiver;

  MainPresenter_LifecycleAdapter(MainPresenter receiver) {
    this.mReceiver = receiver;
  }

  @Override
  public void onStateChanged(LifecycleOwner owner, Lifecycle.Event event) {
    if (event == Lifecycle.Event.ON_CREATE) {
      mReceiver.onCreate();
    }
    if (event == Lifecycle.Event.ON_RESUME) {
      mReceiver.onResume();
    }
    if (event == Lifecycle.Event.ON_PAUSE) {
      mReceiver.onPause();
    }
    if (event == Lifecycle.Event.ON_DESTROY) {
      mReceiver.onDestroy();
    }
  }

  public Object getReceiver() {
    return mReceiver;
  }
}

在这里生成的MainPresenter_LifecycleAdapter类中正是实现了GenericLifecycleObserver接口。而Lifecycling.getCallback正是通过反射来获取自动生成实现GenericLifecycleObserver接口的对象,执行其onStateChanged方法,实现了观察者与Activity生命周期的同步调用。

总结

对于Lifecycles这个lib,首先通过一个ContentProvider进行初始化,监听处于栈顶的Activity的onCreateActivity方法,并通过ReportFragment获取Activity的生命周期,通过FragmentCallback和DestructionReportFragment来获取Fragment生命周期。之后将其生命周期事件分发到已经注册过的Observer并交由ObserverWithState来处理。

附录

官方Demo: https://github.com/googlesamples/android-architecture-components
官方文档:https://developer.android.com/topic/libraries/architecture/lifecycle.html

相关文章
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
异步通信 对于BS(Browser-Server 浏览器)架构,很多情景下server的处理时间较长。 如果浏览器发送请求后,保持跟server的连接,等待server响应,那么一方面会对用户的体验有负面影响; 另一方面,很有可能会由于超时,提示用户服务请求失败。
773 0
|
Web App开发 大数据
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
                                                                               1.
1733 0
|
Web App开发 前端开发 算法
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
import java.util.LinkedHashMap;import java.util.Map; /** * LRU (Least Recently Used)  */public class LRUCache e...
635 0
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
如何获取设备特征码、版本号、激活码?方式一 第一步:打开凯立德移动导航系统,进入地图界面,点击“查找”第二步:在查找页面以“快拼”的输入方式下,输入“AAAAAA”(6个A)
986 0
|
Web App开发 前端开发 关系型数据库
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
云服务器 ECS > Linux操作运维问题 > 应用配置 > linux系统关闭IPv6的方式 linux系统关闭IPv6的方式 IPv6被认为是IPv4的替代产品,它用来解决现有IPv4地址空间即将耗尽的问题。
1053 0
|
Web App开发 Java Apache
|
Web App开发 算法 Java
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
(1)直接插入排序 [java] view plaincopy /** 直接插入排序 **/   /** 数组是引用类型,元素值将被改变 **/   public static void insertSort(i...
708 0
|
Web App开发 前端开发 API
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
     比如RDD里的计算调用了别的组件类里的方法(比如hbase里的put方法),那么序列化时,会将该方法所属的对象的所有变量都序列化的,可能有些根本没有实现序列化导致直接报错。
741 0
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
度量(指标) 定义 活跃用户 指启动应用的用户(去重,即1台设备打开多次会被计为1个活跃用户)。 是衡量一个应用运营情况最基础的一个指标,用以表示用户规模。
640 0
|
Web App开发 存储 大数据
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
大数据元数据和数据管理框架 Apache Atlas实践 今天技术小伙伴占卫同学分享了Apache Atlas元数据管理实践,被atlas的强大的血缘关系管理能力震撼,以下为本次分享内容: •Apache Atlas...
1450 0