虐面试官系列Lifecyele篇 - (2)源码分析之 Event & State

2020-02-17 08:14:40 浏览数 (1)

前言:

原谅我标题党??

Lifecycle系列:

虐面试官系列Lifecyele 篇 -(1)基础讲解

虐面试官系列Lifecyele篇 - (2)源码分析之 Event & State

虐面试官系列Lifecyele篇 - (3)源码分析之注册 & 发送

虐面试官系列Lifecyele篇 - (4)源码分析之响应

待完成:

虐面试官系列Lifecyele 篇 - (5)集成Lifecycle的几种方式的源码差别

又是很久很久没写文章了,最近打算写下Android的又一基础知识: Android 官方架构组件系列。打算把相关的知识点都整理写下,所以本系列的主体为Lifecycle.


正文

其实我们知道,归根到底其实源码讲解主要就:基础类介绍,注册源码,发送源码,响应源码

在虐面试官系列Lifecyele 篇 -(1)基础讲解中,我们讲过三种集成Lifecycle方式,我们上面讲了三种集成方式,其实一个集成方式源码通了,其他都都类似。

本文我们会介绍Lifecycle这个基础类,同时着重讲解State和Event相关知识,因为很多人看过之后,总是忘记具体的这二个内容和对应的关系,及为什么是这样的对应关系。(也有别人问过我,说理解不了),所以本文着重讲这块内容。

1.1 Lifecycle的State和Event分析

1. 房东类:Lifecycle类

我们知道房东是需要把相关信息告诉中介,中介统一进行转述。所以一些相关的所谓的信息值,也都是房东这边就会有,比如价格值等定义。

代码语言:javascript复制
public abstract class Lifecycle {
   
    //'这个方法很直观,就是添加Observer进来,等会看具体的实现内容'
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);

    //'字面意思,移除Observer'
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    
    
    //'获取当前的State值'
    @MainThread
    @NonNull
    public abstract State getCurrentState();
    
    //'Event值'
    public enum Event {
        
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
    }
    
    //'State值'
    public enum State {
        
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
        
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }
}

我们可以看到主要有二类值: Event和State,从字面意思我们就知道,State是当前Lifecycle的状态值,而Event是Lifecycle接下去的动作值

(PS:简单可以理解为房东有二种状态值,一种是具体的房价价格,比如定了房子卖10000一平米,还有一种是动作值,比如涨价1000元一平米,这么简单的类比就更好理解了。)

大家有没有想过,为什么Event值有7个(ON_ANY等会我不会在讨论范围内,所以等会我会说明6个Event),而具体的State值就5个???很多人讲解文章就理所当然的就说有这么XXXX的值,如果让你写Lifecycle源码,你又是否会设计成这样,设计成这几个值???

我们具体来看下这个问题:

如果正常的画图,我估计大家肯定都是画成:

上面这个图估计大家也都看得懂,没有任何问题,因为是横向链条结构,我们可以让它弯曲,这样图片就不会太长了,我们来画第二个图:

没错,当前我们把上面的具体的Event值一一对应,比如ON_RESUME 对齐 ON_PAUSE, ON_CREATE 对齐 ON_DESTORY,但是我们的State的值实在是太多了,有没有办法改变一下???答案当然是可以:

我们可以看到上面这个图片,我们的onPause被我们改名字了,改成了onStart2,当然实际上它跟上面的onStart是有区别的,实质上它是onPause,那我们把名字改了,还能知道吗???答案是可以的,为什么?因为有Event配合,所以就能知道。

可能有些人这里就有点迷糊了,我来举个例子: 比如原来房价为13000一平米,涨了1000,变成了14000,再涨了1000变成了15000,这时候跌了1000,又变回了14000,请问这时候二个14000我可以做区分吗???当然可以,配合动作值就可以,因为一个叫做上涨1000的14000, 一个叫跌了1000的14000。

当然为了好看点,上面的房价变化我们可以写成:

同理我们的onPause虽然名字改成了onStart, 但是因为是通过ON_PAUSE动作值配合,我们知道这时候的onStart其实是onPuaseonStop 更改为onCreate也是一样的道理

所以图片也就变成了:

最后为了对称好看,我们上下用红色的补全了相关缺的地方:

我们拿着我们的图,和Android官方的图比较一下看看是不是一样:

所以以后面试官问你关于State和Event相关的值问题,你可以直接怼对方了。

PS: 同时我这里要额外讲一个关于枚举的小知识点,有利于后面的一些源码的值判断的理解:

比如我们拿State这个枚举来说:

代码语言:javascript复制
public enum State {
        
    DESTROYED,
    
    INITIALIZED,
    
    CREATED,
    
    STARTED,
    
    RESUMED;
}

比如当前,对枚举值比较大小:DESTROYED.compareTo(CREATED),这时候这个值为多少呢??? 我们一步步来看:

代码语言:javascript复制
public final int compareTo(E o) {
    Enum<?> other = (Enum<?>)o;
    Enum<E> self = this;
    if (self.getClass() != other.getClass() && // optimization
        self.getDeclaringClass() != other.getDeclaringClass())
        throw new ClassCastException();
    
    //'我们可以看到最后比较 是Enum的ordinal值,也就是顺序值'
    return self.ordinal - other.ordinal;
}

所以实际上应该是这样的:

代码语言:javascript复制
public enum State {
    //顺序值为0    
    DESTROYED,
    //顺序值为1   
    INITIALIZED,
    //顺序值为2   
    CREATED,
    //顺序值为3   
    STARTED,
    //顺序值为4   
    RESUMED;
}

所以DESTROYED.compareTo(CREATED)的结果为: 0 - 2 = -2;

反过来:CREATED.compareTo(DESTROYED)的结果为:2 - 0 = 2

结语

本文我们可以更容易记住Event & State的相关知识。

0 人点赞