一点点入坑JetPack:Lifecycle源码篇

栏目: IOS · Android · 发布时间: 5年前

内容简介:前言因为业务的原因,自己也开始了JetPack之旅。不得不承认,用上之后:真香。 JetPack以官方的方案,解决了很多我们头疼的问题。JetPack作为一整套的解决方案,不是一篇文章很够解释清楚的。正如官方所说:Android Jetpack 组件是库的集合,这些库是为协同工作而构建的,不过也可以单独采用,同时利用 Kotlin 语言功能帮助您提高工作效率。可全部使用,也可混合搭配!

前言

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

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

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

文章重点部分将聚焦:

一点点入坑JetPack:Lifecycle源码篇

正文

不想看我瞎比比的,也可以直接跳转至官网: 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研究一翻。

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


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

未来版图

未来版图

麻省理工科技评论 / 人民邮电出版社 / 2018-5-1 / CNY 69.80

《麻省理工科技评论》作为世界上历史悠久、影响力极大的技术商业类杂志,每年都会依据公司的科技领军能力和商业敏感度这两个必要条件,从全球范围内选取50家未来可能会成为行业主导的聪明公司。 这些聪明公司,并非都是行业巨头,甚至专利数量、公司所在地以及资金规模都不在考察范围内。 这些公司是“高精尖科技创新”与“能够保证公司利益* 大化的商业模式”的完 美融合。无论公办私营,无关规模大小,这些遍布全球......一起来看看 《未来版图》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器