一点点入坑JetPack:Lifecycle篇

3,286 阅读7分钟

前言

因为业务的原因,自己也开始了JetPack之旅。不得不承认,用上之后:真香。 JetPack以官方的方案,解决了很多我们头疼的问题。JetPack作为一整套的解决方案,不是一篇文章很够解释清楚的。正如官方所说:

Android Jetpack 组件是库的集合,这些库是为协同工作而构建的,不过也可以单独采用,同时利用 Kotlin 语言功能帮助您提高工作效率。可全部使用,也可混合搭配!

所以这将是一个系列文章,一点点的展开我在JatPack应用中的所学所想。(目前公司项目已将全面用Kotlin,JetPack进行了重构,因此很多代码的设计会和我们的业务相结合,所以仁者见仁智者见智啦~)

一点点入坑JetPack:ViewModel篇

一点点入坑JetPack:Lifecycle篇

一点点入坑JetPack:LiveData篇

一点点入坑JetPack:实战前戏NetworkBoundResource篇

一点点入坑JetPack(终章):实战MVVM

文章重点部分将聚焦:

正文

不想看我瞎比比的,也可以直接跳转至官网:developer.android.google.cn/topic/libra…

1、如何管理生命周期

Lifecycle的出现帮我们解决生命周期管理的问题。这一块对于我们日常开发来说的确是比较坑的一点,生命周期处理不当,很容易造成内存泄漏。 为了能让我们业务代码能够感知到生命周期,我们可能会写大量的代码。比如在让Presenter拥有感知生命周期的能力,我们可能会这么做:

public interface IPresenter {
    void onCreate();

    void onStart();

    void onResume();

    void onPause();

    void onStop();

    void onDestroy();
}

然后实现接口,在Activity/Fragment的生命周期中调用这个接口,完成工作。

这种方式完全ojbk。通俗易懂,这里我不评价它的好坏,毕竟没有任何一种解决方案是完美的。所以接下来咱们来看一看官方的Lifecycle是怎样的一种思路。


2、Lifecycle

说破天,这里需要解决的问题是生命周期管理。那么终究还是逃脱不掉一些套路成分在其中。Lifecycle也是如此,从官方的解释中,可见一斑:

Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.

短短一段话,我们可以猜测到这里通过观察者模式的思路去对外响应生命周期变化。闲话少说,直接从代码感受一下。

2.1、使用

从使用上来说,还是比较简单的。实现LifecycleObserver接口:

// 官方demo
class MyObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connectListener() {
        // TODO
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun disconnectListener() {
        // TODO
    }
}

这俩个注解则标志着,当监听组件的onResume()方法被调用,这里我们被注解的方法也会被调用。(当然前提是addObserver了)

有了观察者了,那我们就去找被观察者。很明显,我们想要观察的对象是拥有生命周期的家伙,比如我们常用的Activity/Fragment。此时我们只需要在onResume()之前的某个实际,把这个Observer,add进去即可,比如在onCreate()中:

override fun onCreate(savedInstanceState: Bundle?) {
   lifecycle.addObserver(MyObserver())
}

OK,这样之后我们的MyObserver既可以正常在响应对应生命周期注解下的方法了。

不过,我相信这样写的朋友,回过来喷我!根本就调不到lifecycle!!

没错,我们常规的Activitiy/Fragment就是调不到...它压根就没这这个方法。

2.2、androidx

这里解释一下,上文中lifecyle其实就是调用Activity/Fragment中的这个方法:

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

有朋友应该提着刀过来了,我tm没有这个方法!兄die,把刀放下,不是没有是import不一样。接下来让我们慢慢来。我使用的这个Fragment的package是这样的:androidx.fragment.app;。看到端倪了吧?androidx,没错,这是为了完美支持JatPack所重新规划出来的包。

当然,也不一定非要用androidx。

Fragments and Activities in Support Library 26.1.0 and later already implement the LifecycleOwner interface.

所以,升库就ok了。这时有小伙伴可能会说了:我不想升库怎么办。这个问题问得好,不想升库,不想升库..就不升呗。

当然我相信,一定有小伙伴注意到一个问题,那就是getLifecycle()是一个接口,那么也就是说我们可以自己实现?没错是这样...(这tm不废话么)

这就是我们自定义的关键。

2.3、LifecycleOwner

假设我们的Activity不支持getLifecycle()咋整?这里直接上官方的代码:

class MyActivity : Activity(), LifecycleOwner {
    private lateinit var mLifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        mLifecycleRegistry = LifecycleRegistry(this)
        mLifecycleRegistry.markState(Lifecycle.State.CREATED)
        
        mLifecycleRegistry.addObserver(MyObserver())
    }

    public override fun onStart() {
        super.onStart()
        mLifecycleRegistry.markState(Lifecycle.State.STARTED)
    }

    override fun getLifecycle(): Lifecycle {
        return mLifecycleRegistry
    }
}

就这样,结束了。说实话,到这就这的没有什么好讲的了。

通过代码,我们可以看出来,LifecycleRegistry是我们的被观察者,它被初始化在拥有生命周期的Activity中,而我们的Observer也被add()到其中,此外还有诸如markState(Lifecycle.State.CREATED)的方法调用。

因此,到这无需多言,各位小伙伴恐怕已经明白了Lifecycle是如何帮我们管理生命周期的了。

2.4、小总结

这几段代码下来,我相信有的朋友已经差不多了解Lifecycle的思路了。一个很标准的观察者模式:这里的LifecycleRegistry(系统帮我们实现的Lifecycle的实现类),持有想要监听这个LifecycleOwner的Observer。然后通过markState(),去遍历所有Observer,通知其生命周期发生变化。


3、原理

聊完了普通用法,咱们来看一下原理。不得不说,Lifecycle实现的原理还是比较骚的,各种骚操作简直是乱花渐欲迷人眼。

咱们在上述的MyObserver中加了注解,所以先看看注解为我们带来了什么。通过注解生成器,我们可以看到在build中得到了下边这个class:

public class MyObserver_LifecycleAdapter implements GenericLifecycleObserver {
    final MyObserver mReceiver;

    LifecycleObserverDemo_LifecycleAdapter(MyObserver receiver) {
        this.mReceiver = receiver;
    }

    @Override
    public void onStateChanged(LifecycleOwner owner, Lifecycle.Event event) {
        mReceiver.onAny(owner,event);
        if (event == Lifecycle.Event.ON_RESUME) {
            mReceiver.connectListener();
        }

        if (event == Lifecycle.Event.ON_PAUSE) {
            mReceiver.disconnectListener();
        }
    }

    public Object getReceiver() {
        return mReceiver;
    }
}

很清晰,我们能够看到,在onStateChanged(LifecycleOwner owner, Lifecycle.Event event)中通过对应的Event就可以调用到我们MyObserver中注解的方法。

那么问题来了:onStateChanged被谁调用的呢?通过上边的例子,我们知道想要Observer能够感应生命周期要么使用内置好的Lifecycle(getLifecycle()),要么自己去实现(LifecycleOwner)。接下来咱们就分这俩种情况来看一看具体的实现原理。

3.1、自定义LifecycleOwner

这一步的源码还是比较的简单直接的,我们可以直接在LifecycleRegistry中的markState(Lifecycle.State.STARTED)一探究竟,一层层的调用下来,我们抛弃一些逻辑判断之后,可以看到一些关键的内容:

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

可以看到,这部分会很直白的调用到注解生成class中的onStateChanged(),完成生命周期的感知。

3.2、getLifecycle()

getLifecycle()的方式,同样是返回了一个LifecycleRegistry。因此,最开始我认为系统因此在对应的生命周期完成对上3.1一样的调用。不过看把发现自己还是太年轻。

SupportActivity中,的onCreate方法中,我们可以看到这样的调用:

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
}

是不是感觉到一丝丝熟悉?使用Fragment做生命周期分离管理在很多框架中都出现。接下来我们就好好看看这个ReportFragment

@Override
public void onResume() {
    super.onResume();
    dispatchResume(mProcessListener);
    dispatch(Lifecycle.Event.ON_RESUME);
}

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中的方法了。

尾声

当然仅凭这些,对于我们来说还远远不够,因此Google还拿出了ViewModelLiveData等相辅相成的有趣模块。下边的文章将走进:ViewModel篇。

许久没有写文章了,一来是最近的确很忙;二来自己也刚开始搞JetPack这一套。学的过程中渐渐发现JatPack属实比较有意思。所以决定好好的把JetPack研究一翻。

这篇文章就算是自己回归写文章的先导篇吧~

我是一个应届生,最近和朋友们维护了一个公众号,内容是我们在从应届生过渡到开发这一路所踩过的坑,以及我们一步步学习的记录,如果感兴趣的朋友可以关注一下,一同加油~

个人公众号:IT面试填坑小分队