前语

Lifecycle即生命周期,作为Android开发者,咱们对生命周期可太了解了,由于咱们不只经常在ActivityFragment的生命周期函数比方onCreateonResume等中做一些逻辑操作;而且组件的生命周期操控不当的话,可能会导致内存走漏,或许一些无法预想的成果,比方在后台恳求网络操作的协程生命周期,要是大于所需求展现UI的界面的生命周期时,就会导致不必要资源糟蹋。

已然ActivityFragment、协程、ViewModelLiveData,甚至咱们常用的Handler等一切方针,都需求严格管理生命周期,所以管理这些组件的生命周期就十分重要,这儿大约能得到2点关于生命周期的需求:

  • ActivtiyFragment这种常用的、显现UI的组件,搞一个一致的生命周期表明规矩,这样就能够极大地便利开发者。

    比方咱们都希望在页面临用户可见时,才更新UI,对用户不行见时,更新UI是无用功。可是比方Fragment就比Activity多了onCreateViewonViewCreated等几个生命周期函数,FragmentView关于可见这个判别就和Activity不相同了,这就导致开发者完结一个功用,需求对接多个组件。

  • 能够获取和监控组件的一致生命周期函数改动。比方不论是Activity仍是Fragment,咱们都希望在回调其onDestroy()办法前,释放一些资源,防止形成内存走漏和资源糟蹋。

所以Lifecycle组件就被开发出来了,面临需求对接多个组件的杂乱状况,一个有用的办法便是笼统出一层,而Lifecycle的思维也是如此,让本来开发者需求多个组件的状况下,现在就变成了对接一个组件。

Jetpack | Lifecycle全解析

如上图所示,有了Lifecycle后,就能够一致组件的生命周期了,这样咱们在开发时就能够面向Lifecycle这一个组件了,这儿咱们以运用StateFlow为例,一般是调用LifecycleOwner(生命周期持有者)的repeatOnLifecycle办法:

//该办法为lifecycle-runtime-ktx中办法,用于监听Satate类型的uiState的改动
public suspend fun LifecycleOwner.repeatOnLifecycle(
    state: Lifecycle.State,
    block: suspend CoroutineScope.() -> Unit
): Unit = lifecycle.repeatOnLifecycle(state, block)

该办法合作StateFlow运用以抵达和运用LiveData相同的效果,测验代码如下:

class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
            // 当LifecycleOwner的状况在STARTED及以上时,会触发block履行
            // 当ON_STOP事情产生时,block协程会被撤销
            // 当LifecycleOwner接收到ON_START事情时,会从头履行block
            lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    uiStateFlow.collect { uiState ->
                        updateUi(uiState)
                    }
                }
            }
        }
    }

从这儿代码注释咱们能够看出,这儿其实完结了相似LiveData的效果:会在Activity可见时绘制UI,在Activity毁掉时撤销协程,保证协程的生命周期可控,能够有用地节省资源和防止内存走漏。

而这个的要害办法repeatOnLifecycleLifecycleOwner的扩展函数,这儿不只仅ActivityLifecycleOwnerFragment也是完结该接口,这也便是前面所说的咱们开发新功用时只需求面临Lifecycle这一个笼统层的组件即可。

正文

已然咱们想把生命周期给笼统出来,再结合生命周期的效果,这儿咱们就能够考虑一下,应该给笼统为几个部分。在Android中的Lifecycle结构库中,首要触及的类如下:

classDiagram
class LifecycleOwner{
    <<interface>>
    ---
    +Lifecycle getLifecycle()
}
LifecycleOwner --> Lifecycle
class Lifecycle{
    <<Abstract>>
    AtomicReference<Object> mInternalScopeRef
    +addObserver(@NonNull LifecycleObserver observer) void
    +removeObserver(@NonNull LifecycleObserver observer)
    +getCurrentState() State
}
Lifecycle ..> LifecycleObserver
class LifecycleObserver{
    <<interface>>
    ---
}
Lifecycle ..> State
class State{
    <<enum>>
    DESTROYED
    INITIALIZED
    CREATED
    STARTED
    RESUMED
    +isAtLeast(@NonNull State state) boolean
}
class FullLifecycleObserver{
    <<interface>>
}
LifecycleObserver <|-- FullLifecycleObserver
class DefaultLifecycleObserver{
    <<interface>>
}
FullLifecycleObserver <|-- DefaultLifecycleObserver
class LifecycleEventObserver{
    <<interface>>
}
LifecycleObserver <|-- LifecycleEventObserver
class Activity{
    +getLifecycle() Lifecycle
}
class Fragment{
    +getLifecycle() Lifecycle
}
LifecycleOwner <|.. Activity
LifecycleOwner <|.. Fragment

这儿假设对UML类图还不了解的,能够检查文章:# 功率进步 | UML类图。

从上面UML类图咱们能够知道如下信息:

  • 咱们常用的ActivityFragment都是完结了LifecycleOwner接口,即为生命周期持有者,而LifecycleOwner是单办法接口,咱们能够调用其getLifecycle()办法回来一个Lifecycle方针。

  • Lifecycle是一个笼统类,从其界说的3个办法来剖析,首要就2个效果:

    • 经过添加和移除调查者的调查者模式,咱们能够监听Lifecycle派发的事情,调查者一致界说为LifecycleObserver接口。
    • 经过getCurrentState()办法,咱们能够获取当时Lifecycle的状况,这儿的状况State是一个枚举类型。

这也印证了文章刚开端咱们笼统Lifecycle的原意,咱们先不急着探求其原理,咱们先来考虑一下,咱们怎么运用这些供给的API

Lifecycle的根本用法

第一种用法便是前面所说的,能够监听Lifecycle所派发的生命周期事情,测验代码如下:

//Activity中代码
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    lifecycle.addObserver(object : LifecycleEventObserver {
        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
            Logger.d("source = $source  event = $event")
        }
    })
}

由于Activity完结了LifecycleOwner接口,所以这儿能够获取Lifecycle方针,经过addObserver()办法能够添加调查者,这儿的LifecycleEventObserverLifecycleObserver的子接口:

classDiagram
class LifecycleObserver{
    <<interface>>
    ---
}
class LifecycleEventObserver{
    <<interface>>
    +onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) void
}
LifecycleObserver <|-- LifecycleEventObserver
class Event{
    <<enum>>
    ON_CREATE
    ON_START
    ON_RESUME
    ON_PAUSE
    ON_STOP
    ON_DESTROY
    ON_ANY
}
LifecycleEventObserver ..> Event

而这儿的生命周期事情便是Event,关于Activity来说,其便是对应了其几个生命周期办法,所以上面测验代码中,咱们把APP页面翻开再封闭,打印如下:

Jetpack | Lifecycle全解析

第二种用法便是前面所说的能够调用getCurrentState()办法来获取当时Lifecycle的状况,关于状况State总共界说了5种枚举,至于为什么是5种,咱们等会说原理时细说,这儿咱们大约和生命周期函数履行完的状况对应起来。

这儿咱们以LiveData来举例,LiveData具有生命周期感知才能的调查者容器,所以有个特性:运用LiveData为数据源,做数据驱动来更新UI时,当UI页面不行见时,是不会更新UI的

已然和生命周期有关,那就有必要得用Lifecycle了,下面是运用LiveData更新UI:

//Activity中代码
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewModel.uiState.observe(this){
        updateUI(it)
    }
}

这儿调用了LiveDataobserve办法:

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer){
        assertMainThread("observe");
        //注释1
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        ...
}

这儿咱们能够发现该办法第一个参数是LifecycleOwner,即生命周期持有者,而咱们所了解的Activity就完结了该接口。在注释1处,会判别Lifecycle的当时状况,假设是DESTROYED的话,就没必要继续操作了,即当时生命周期组件现已是毁掉状况了,彻底没必要更新UI了。

这只是LiveData运用LifecyclegetCurrentState()办法获取状况的一个运用之处,更多关于LiveData的生命周期感知才能,咱们后边介绍LiveData时再说。

第三种运用Lifecycle组件的用法便是简化代码,核心思维是别离关注点,让本来需求在Activity/Fragment的生命周期办法中写的逻辑,给整理到一个生命周期调查者中,这儿咱们运用官方比方:

class MyActivity : AppCompatActivity() {
    //地理位置监听器
  private lateinit var myLocationListener: MyLocationListener
  override fun onCreate(...) {
        //在onCreate办法中,创立监听器,依据监听器更新UI
    myLocationListener = MyLocationListener(this) { location ->
      // update UI
    }
  }
  public override fun onStart() {
    super.onStart()
        //判别监听器是否被调用,开启服务
    Util.checkUserStatus { result ->
      // what if this callback is invoked AFTER activity is stopped?
      if (result) {
        myLocationListener.start()
      }
    }
  }
  public override fun onStop() {
    super.onStop()
        //及时暂停服务,防止资源糟蹋和内存走漏
    myLocationListener.stop()
  }
}

上述代码我信任许多开发者都写过,为了服务能正常创立、发动以及封闭,咱们有必要坚持服务的生命周期和Activity一致,这样能够防止内存走漏和防止资源糟蹋,可是这就导致每个生命周期函数中逻辑过多,这时咱们就能够运用Lifecycle来进行优化

相似第一种运用办法,咱们需求监听Lifecycle的生命周期改动事情,一同做一些处理,所以咱们自界说一个调查者,代码如下:

//承继至DefaultLifecycleObserver
internal class MyLocationListener(
    private val context: Context,
    private val lifecycle: Lifecycle,
    private val callback: (Location) -> Unit
): DefaultLifecycleObserver {
  private var enabled = false
    init{
        lifecycle.addObserver(this)
    }
    //阐明ON_START事情产生,能够看成Activity的onStart函数回调
  override fun onStart(owner: LifecycleOwner) {
    if (enabled) {
      // connect
    }
  }
  fun enable() {
    enabled = true
    if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED))  {
      // connect if not connected
    }
  }
    //阐明ON_PAUSE事情产生,能够看成Activity的onStop函数回调
  override fun onStop(owner: LifecycleOwner) {
    // disconnect if connected
  }
    ...
}

已然是添加调查者,所以有必要是承继至LifecycleObserver接口,前面说了,这是一个空办法接口,第一种运用办法中,咱们是运用了LifecycleEventObserver,这儿咱们运用DefaultLifecycleObserver接口,承继联系如下:

classDiagram
class LifecycleObserver{
    <<interface>>
    ---
}
class FullLifecycleObserver{
    <<interface>>
    ---
    +onCreate(LifecycleOwner owner) void
    +onStart(LifecycleOwner owner) void
    +onResume(LifecycleOwner owner) void
    +onPause(LifecycleOwner owner) void
    +onStop(LifecycleOwner owner) void
    +onDestroy(LifecycleOwner owner) void
}
class DefaultLifecycleObserver{
    <<class>>
    ---
    +onCreate(LifecycleOwner owner) void
    +onStart(LifecycleOwner owner) void
    +onResume(LifecycleOwner owner) void
    +onPause(LifecycleOwner owner) void
    +onStop(LifecycleOwner owner) void
    +onDestroy(LifecycleOwner owner) void
}
LifecycleObserver <|-- FullLifecycleObserver
FullLifecycleObserver <|-- DefaultLifecycleObserver

这儿的差异清楚明了,便是Event给细分为了这几个回调函数,一同供给了默许完结。

界说完自界说的调查者后,运用如下:

class MyActivity : AppCompatActivity() {
  private lateinit var myLocationListener: MyLocationListener
  override fun onCreate(...) {
        //只需求在onCreate中调用即可
    myLocationListener = MyLocationListener(this, lifecycle) { location ->
      // update UI
    }
    Util.checkUserStatus { result ->
      if (result) {
        myLocationListener.enable()
      }
    }
  }
}

比较于最开端的代码,咱们只需求在onCreate这一个生命周期函数中进行初始化即可,能够免除在多个生命周期函数中写逻辑,能够简化代码

第四种用法首要是防备内存走漏,在代码规划中,有个十分重要的原则是架构和事务别离,就比方咱们常见的网络传输协议,TCP现已供给了可靠交给,就不需求咱们在事务运用层里边再写关于可靠交给的逻辑了。

在整个Jetpack组件都是遵循这种原则的,比方咱们文章最开端的比方,repeatOnLifecycle()办法中收集数据的协程,就会当Lifecycle处于DESTROYED时主动撤销,这样就把适宜机遇撤销协程,防止资源糟蹋和内存走漏这个架构规划和事务逻辑给分开了,而不必咱们在事务处理时,还考虑这些。

除此之外,还有十分多的小比方,比方这儿防止内存走漏的Handler:

//这儿承继Handler,完结LifecycleEventObserver接口
class LifecycleHandler(val lifecycleOwner: LifecycleOwner) : Handler(),
    LifecycleEventObserver {
    init {
        addObserver()
    }
    private fun addObserver() {
        lifecycleOwner.lifecycle.addObserver(this)
    }
    //当生命周期持有者状况为DESTROYED时,移除一切音讯和回调,保证能够正常被GC收回
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        if (event == Lifecycle.Event.ON_DESTROY) {
            removeCallbacksAndMessages(null)
            lifecycleOwner.lifecycle.removeObserver(this)
        }
    }
}

由于ActivityFragment都是完结了LifecycleOwner接口,所以一切依靠ActivityFragment的类,都能够采取相似战略,比方Dialog等,将内存走漏消除在架构层逻辑。

看到这儿,我信任你会有一些疑问。比方DefaultLifecycleObserver中的onCreate()回调是怎么和Activity中的onCreate()回调坚持联动的?有没有先后调用顺?换成Fragment为生命周期持有者,会不会有什么改动?

带着这些疑问,咱们来剖析一下其源码。

Lifecycle解析

已然Lifecycle生命周期的笼统,首要用于获取当时生命周期状况以及派产生命周期事情,那么ActivityFragment的生命周期函数个数是不相同的,所以这儿需求界说一个愈加通用的笼统层。

按照规划,表明Lifecycle状况是State,它总共有5种状况;而表明状况切换的事情,总共有7个,这儿了解起来比较要害,官方有一个图如下:

Jetpack | Lifecycle全解析

这儿咱们Activity为例,来解释一下这几种State意义:

  • 依据枚举界说,每个枚举值都有一个int类型ordinal值,表明界说枚举的次序,这个值默许便是0到4State.DESTROYED最小,State.RESUMED最大,这也便是状况高低的说法,也是isAtLeast()办法履行的依据:

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

    比方调用isAtLeast(STARTED)true,就阐明当时Lifecycle状况为STARTED或许RESUMED

  • 咱们所熟知的Activity的生命周期函数如图:

    Jetpack | Lifecycle全解析

这儿不算onRestart()办法总共有6个,可是在前面咱们界说的LifecycleState却没有这么多,所以这儿要留意,这儿的State更多的表明是一种状况,而非和生命周期函数一一对应

  • 这儿对每一种State做详尽讲解:
    • DESTROYED:它是最小状况,表明现已毁掉的状况,在这个状况的Lifecycle将不再分发任何生命周期事情Event,这个状况Activity onDestroy()调用前抵达
    • INITIALIZED:表明初始化状况,表明Activity现已被创立,可是还没有回调onCreate()办法,即在onCreate()办法回调前的状况是该状况。
    • CREATED:表明已创立的状况,留意这种状况不只仅在ActivityonCreate()办法回调后抵达,而且onStop回调前也是属于该状况,简略来说便是处于CREATED状况时,组件现已被创立,可是不行见且不行交互
    • STARTED:表明可见状况,可是无法交互,所以这种状况onStart()回调后和onPause()回调前抵达
    • RESUMED:表明处于可交互的running状况,这也只有在onResumd()回调后抵达

上面咱们以Activity生命周期为例,剖析了各种State的效果,能够总结为下图:

Jetpack | Lifecycle全解析

这儿咱们能够知道一个完好的Activity生命周期,State状况是从小到大,再到小,这也是契合咱们笼统生命周期的理念:咱们更偏重想知道当时Lifecycle的状况,比方是否可见,是否现已被毁掉,便利对应逻辑操作,而生命周期改动的事情,由Event来界说和派发。

说完了State,咱们来看看其向调查者所派发的Event事情,这儿搞清楚一个规划思路:Lifecycle的状况切换是由Event所导致,所以能够以为State便是一个图中的节点,而Event便是衔接节点的边。

前面咱们是以Activity来阐明State的,其实真实的Event规划的差不多,也是对应着几种回调函数来规划的,Event是枚举类,共有6种事情,以及一系列状况切换办法,咱们举个简略比方来阐明Event工作流程:

sequenceDiagram
Activity ->> Observer:注册调查者
Activity -->> Activity:onCreate()回调
Activity ->> Observer:派发ON_CREATE事情
Observer -->> Observer:逻辑处理

所以Event的界说共如下几种:ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、ON_STOP和ON_DESTROY,至于各自的意义,这儿不多说了,便是和生命周期回调函数对应。

这儿有个难点,便是Event中界说的几个办法,合作State运用,咱们来剖析一下。

downFrom办法界说如下:

public static Event downFrom(@NonNull State state) {
    switch (state) {
        case CREATED:
            return ON_DESTROY;
        case STARTED:
            return ON_STOP;
        case RESUMED:
            return ON_PAUSE;
        default:
            return null;
    }
}

解释:当从参数state离开往更低的状况切换,需求分发的Event。这儿的downFrom函数名咱们要分开看,其间down表明动词,表明向下from便是阐明从哪个状况开端,这儿结合前面的状况图一同,看代码完结:

  • 咱们从CREATED状况开端,向下降低状况,依据状况图,它下一个状况便是DESTROY,需求派发ON_DESTROY事情来完结状况切换。
Jetpack | Lifecycle全解析
  • 咱们从STARTED状况开端,向下降低状况,依据状况图,它的下一个状况是CREATED,需求派发ON_STOP事情来完结状况切换。
Jetpack | Lifecycle全解析

相似的办法还有downTo

public static Event downTo(@NonNull State state) {
    switch (state) {
        case DESTROYED:
            return ON_DESTROY;
        case CREATED:
            return ON_STOP;
        case STARTED:
            return ON_PAUSE;
        default:
            return null;
    }
}

其间down是动词表明向下,to表明希望抵达某个状况,这儿咱们需求留意一点:不论是down,仍是后边要说的up,状况改动只能一步一步来

我想从RESUMED状况,下降到CREATED状况,依据状况图有必要先下降到STARTED状况,再下降到CREATED状况,所以咱们再看前面downTo的完结,当希望下降的状况是DESTROYED时,依据一次只能下降一步的原则,其实它的上一个状况便是CREATED,所以需求派发ON_DESTROY事情来完结状况切换。

这儿还有相似的upFrom()upTo()办法,咱们就不剖析了,可是咱们要了解其规划思路:这些办法有什么用?

不论是down仍是up,它的意图都是改动状况State的值,那我直接改动其值不就好了吗?为什么要知道每一步改动的事情呢?

这就触及一个思维:永久是事情驱动状况改动,即事情导致状况改动。这儿表现为2个方面:

  • 关于Activity这种生命周期持有者来说,永久都是其自己的onCreate()办法回调后,收到了ON_CREATE事情,其状况才改动为CREATED状况。
  • 关于新添加的调查者来说,调查者默许状况是初始化状况,这时假设被调查者现已是RESUMED状况,这时需求进步新添加的调查者的状况,从INITIALIZED进步到RESUMED,在这个进程中,需求一步一步派发Event,直到进步到RESUMED状况。

这2个方面第一个十分好了解,咱们来看第二点,第二点其实就对应着Lifecycle的2个重要函数:addObserverremoveObserver

这儿暂时还没有到剖析原理的当地,咱们能够先说定论,等后边剖析原理时再验证一下:

  • 关于addObserver办法,它是添加一个调查者,当被调查者的状况产生改动时,会告诉调查者

被添加的调查者状况,会被进步到和被调查者相同的状况。比方LifecycleOwner的状况是STARTED,这个刚被添加的调查者,就需求派发ON_CREATEON_START事情。

  • 关于removeObserver办法,它是移除一个调查者

到这儿咱们只是在接口层剖析了Lifecycle的运用,那么接下来便是重点工作了,咱们来剖析一下Lifecycle是怎么对ActivityFragment进行笼统和封装的。

Lifecycle原了解析

从前面接口和运用剖析,咱们知道Lifecycle是调查者模式,能够用来获取当时LifecycleState,以及经过调查者来监听Lifecycle所派发的Event

所以这儿咱们需要知道Lifecycle是怎么进行笼统的,是怎么添加/移除调查者,以及怎么派发Event,即

Jetpack | Lifecycle全解析

这一部分的工作原理,咱们先以Activity为例来解析源码。

话不多说,咱们仍是先来看看相关类的联系:

classDiagram
ViewModelStoreOwner <|.. ComponentActivity
LifecycleOwner <|.. ComponentActivity
ComponentActivity <|-- FragmentActivity
FragmentActivity <|-- AppCompatActivity
class ComponentActivity{
    -LifecycleRegistry mLifecycleRegistry
    +getLifecycle() Lifeycle
}
ComponentActivity --> LifecycleRegistry
Lifecycle <|-- LifecycleRegistry
class Lifecycle{
    <<Abstract>>
    AtomicReference<Object> mInternalScopeRef
    +addObserver(@NonNull LifecycleObserver observer) void
    +removeObserver(@NonNull LifecycleObserver observer)
    +getCurrentState() State
}
class LifecycleRegistry{
    -State mState
    -FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap
    -WeakReference<LifecycleOwner> mLifecycleOwner
    +handleLifecycleEvent(@NonNull Lifecycle.Event event) void
    +addObserver(@NonNull LifecycleObserver observer) void
    +removeObserver(@NonNull LifecycleObserver observer) void
    +getCurrentState() State
}
AppCompatActivity <|-- MainActivity

这儿咱们能够发现ComponentActivity完结了LifecycleOwner接口,即咱们平常运用Activity便是生命周期持有者。

咱们调用getLifecycle()办法时,其实便是回来ComponentActivity中界说的LifecycleRegistry类型的mLifecycleRegistry成员变量:

public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
}
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

而且LifecycleRegistry完结了Lifecycle接口,所以这儿运用了署理模式,一切操作都由这个LifecycleRegistry来完结

咱们先不去看其源码,咱们先来剖析一下Activity生命周期事情是什么时分派发给LifecycleRegistry的。

本来我以为分产生命周期事情,会在ComponentActivity的各个生命周期回调函数中调用LifecycleRegistry办法来派发事情,看了源码发现是运用了ReportFragment来完结的,调用联系如下:

sequenceDiagram
ComponentActivity ->> LifecycleRegistry: 持有变量
Note right of LifecycleRegistry:INITIALIZED
LifecycleRegistry ->> Observer:注册调查者
ComponentActivity ->> ComponentActivity:onCreate()
ComponentActivity ->> ReportFragment:injectIfNeededIn(this)
ComponentActivity -->> ReportFragment:更新依靠的Fragment生命周期
ReportFragment ->> ReportFragment:onActivityCreated()
ReportFragment ->> ReportFragment:dispatch(Event.ON_CREATE)
ReportFragment ->> ReportFragment:dispatch(getActivity(), Event.ON_CREATE)
ReportFragment ->> LifecycleRegistry:handleLifecycleEvent(Event.ON_CREATE)
Note right of LifecycleRegistry:CREATED
LifecycleRegistry ->> Observer:notify()

上面黄色的Note表明Lifecycle的当时State,由这儿咱们能够验证最开端说的State意义:其间INITIALIZED初始化状况表明组件现已被创立,可是没有收到ON_CREATE事情,当收到ON_CREATE事情,状况切换到CREATED状况

这儿为什么能够运用ReportFragment的生命周期回调函数中来分发Activity的生命周期Event呢?这就触及了ActivityFragment生命周期函数的调用联系,如下图:

Jetpack | Lifecycle全解析

尽管这儿FragmentActivity多几个生命周期函数,可是一点点不影响咱们运用Fragment的生命周期来派发其所依靠的Activity的生命周期事情。

经过简略检查源码,对应联系如下:

  • ActivityON_CREATE事情在Fragment中的onActivityCreated()办法中分发。
  • ON_STARTON_RESUMEON_PAUSEON_STOPON_DESTROY都是由其同名生命周期办法中分发。

这儿分发事情的办法便是调用LifeycleRegistryhandleLifeEvent()办法,该办法咱们后边细说。

说完了Activity是怎么适配Lifecycle的,首要便是能够正确地、合理地派发EventLifecycleRegistry,咱们接着来看一下Fragment的流程,由于Fragment有一点不相同,它在派发Event有2套逻辑

咱们一般运用LiveData作为调查者容器,在FragmentonViewCreated()办法中进行数据调查和更新UI:

Jetpack | Lifecycle全解析

这儿咱们运用thisFragment方针作为LifecycleOwner居然会报错,提示运用viewLifecycleOwner作为生命周期持有者,那这儿这2个生命周期持有者有什么差异呢?假设强行运用this会有什么问题呢?

带着问题看源码,就有了探求思路,首要便是Fragment它是完结了LifecycleOwner接口的,相关类如下:

classDiagram
ViewModelStoreOwner <|.. Fragment
LifecycleOwner <|.. Fragment
Fragment <|-- BusinessFragment
class Fragment{
    +LifecycleRegistry mLifecycleRegistry
    +getLifecycle() Lifecycle
}
Lifecycle <|-- LifecycleRegistry
class Lifecycle{
    <<Abstract>>
    AtomicReference<Object> mInternalScopeRef
    +addObserver(@NonNull LifecycleObserver observer) void
    +removeObserver(@NonNull LifecycleObserver observer)
    +getCurrentState() State
}
class LifecycleRegistry{
    -State mState
    -FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap
    -WeakReference<LifecycleOwner> mLifecycleOwner
    +handleLifecycleEvent(@NonNull Lifecycle.Event event) void
    +addObserver(@NonNull LifecycleObserver observer) void
    +removeObserver(@NonNull LifecycleObserver observer) void
    +getCurrentState() State
}
Fragment --> LifecycleRegistry

Activity相同,经过getLifecycle获取的仍旧是LifecycleRegistry实例,工作机制相同,当Fragment的生命周期改动时,经过调用handleLifeEvent()来保存和处理事情,咱们只需求知道在什么时分会派发事情即可,下面是源码总结:

调用链 派发的Event Lifecycle状况
Fragment()结构函数 -> initLifecycle()创立LifecycleRegistry实例 INITIALIZED
performCreate() -> onCreate() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) Lifecycle.Event.ON_CREATE CREATED
performStart() -> onStart() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START) Lifecycle.Event.ON_START STARTED
performResume() -> onResume() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME) Lifecycle.Event.ON_RESUME RESUMED
performPause() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE) -> onPause() Lifecycle.Event.ON_PAUSE STARTED
performStop() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP) -> onStop() Lifecycle.Event.ON_STOP CREATED
performDestroy() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY) -> onDestroy() Lifecycle.Event.ON_DESTROY DESTROYED

上面的代码调用流程再合作文章刚开端说的图,是不是能够完美契合上了!尤其是派发事情和生命周期回调函数的先后问题

从这儿的生命周期回调来看,咱们能够得出定论:getLifecycle()获取的Lifecycle,其代表Fragment的生命周期

getViewLifecycleOwner()获取的Lifecycle有什么差异呢?话不多说,直接看源码,触及的相关类:

classDiagram
Fragment <|-- BusinessFragment
class BusinessFragment{
    +getViewLifecycleOwner() LifecycleOwner
}
class Fragment{
    +FragmentViewLifecycleOwner mViewLifecycleOwner
    +getViewLifecycleOwner() LifecycleOwner
}
Fragment --> FragmentViewLifecycleOwner
class FragmentViewLifecycleOwner{
    -LifecycleRegistry mLifecycleRegistry
    +handleLifecycleEvent(@NonNull Lifecycle.Event event) void
}
FragmentViewLifecycleOwner --> LifecycleRegistry
class LifecycleRegistry{
    +handleLifecycleEvent(@NonNull Lifecycle.Event event) void
}
Lifecycle <|-- LifecycleRegistry
class SavedStateRegistryOwner{
    <<interface>>
    +getSavedStateRegistry() SavedStateRegistry
}
LifecycleOwner <|-- SavedStateRegistryOwner
SavedStateRegistryOwner <|-- FragmentViewLifecycleOwner
ViewModelStoreOwner <|-- FragmentViewLifecycleOwner

能够发现这儿运用了署理模式,可是署理的是LifecycleOwner象,所以这儿的核心代码便是FragmentViewLifecycleOwner的完结,在这儿面咱们仍旧仍是运用LifecycleRegstry来管理和处理Event,所以咱们的要害仍是看看在什么时分调用了Event,总结如下:

调用链 派发的Evnet viewLifecycle状况
performCreateView() -> FragmentViewLifecycleOwner(this, getViewModelStore())调用结构函数 -> onCreateView() -> mViewLifecycleOwner.initialize() INITIALIZED
restoreViewState() -> onViewStateRestored(savedInstanceState) -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) Lifecycle.Event.ON_CREATE CREATED
performStart() -> onStart() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START) Lifecycle.Event.ON_START STARTED
performResume() -> onResume() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME) Lifecycle.Event.ON_RESUME RESUMED
performPause() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE) -> onPause() Lifecycle.Event.ON_PAUSE STARTED
performStop() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP) -> onStop() Lifecycle.Event.ON_STOP CREATED
performDestroyView() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY) -> onDestroyView() Lifecycle.Event.ON_DESTROY) DESTROYED

从这儿的调用链和前面Fragment自己的Lifecycle做比较,咱们能够明显发现ON_STARTON_RESUMEON_PAUSEON_STOP事情的派发机遇和Fragment自己的Lifecycle是相同的。

而其他几个Event的派发就和FragmentView的联系愈加亲近了,这儿也就阐明一件事:Fragment的生命周期和其View的生命周期是不相同的getViewLifecycleOwner()回来的viewLifecycleOwner,表明的是FragmentView的生命周期

至于差异,咱们能够看一张官方的图:

Jetpack | Lifecycle全解析

从这张图咱们能够得出以下定论:

  • ViewLifecycleFragmentLifecycle要短。
  • FragmentLifecycleCREATED时,ViewLifecycle可能还没有创立,即使创立了,也会在View创立完结后才处于CREATED状况。
  • Fragment还处于CREATED状况时,就会调用onDestroyView()函数,这时ViewLifecycle就处于DESTROYED状况了。

剖析完上面定论,咱们就能够解决这个问题了:

Jetpack | Lifecycle全解析

为什么这儿要运用ViewLifecycle而不是挑选FragmentLifecycle

原因十分简略,也便是咱们希望更新UI是依据FragmentView的生命周期来做处理,而不是Fragment的生命周期,那假设用错了,会导致什么问题呢?

这儿触及LiveData一个特性:LifecycleOwnerLifecycle处于DESTROYED状况时,会主动removeLiveData调查者

所以这儿的uiData会在owner处于DESTROYED时主动移除监听,能够防止内存走漏,而且只更新可见的有用的UI信息

这儿出问题的场景便是Fragment切换时,能够把FragmentA加入到回退栈中,而且翻开新FragmentB,这时FragmentA会履行onDestroyView()办法,可是不会履行onDestroy()办法,这时由于Fragment并没有被毁掉;

这儿假设运用Fragment的作为LifecycleOwnerFragmentA就不会移除uiData这个调查者,由于它没有到DESTROYED状况;这时再按回来键,FragmentB出栈,FragmentA又从头显现出来,这时会从头回调onViewCreated()办法,又会从头添加一遍uiData这个调查者,导致重复添加调查者

可是运用viewLifecycleOwner就不会呈现这种状况,依据前面生命周期图可知,当履行到onDestroyView()办法时,Lifecycle就处于DESTROYED状况了,这时能够正常移除调查者

LifecycleRegistry原了解析

看了前面的运用以及解析,我信任你必定刻不容缓地想对LifecycleRegistry进行探求了,看看官方是怎么完结一个Lifecycle的。

这儿有关LifecycleRegistry内容比较多,我一向坚持一个看源码便是一个继续学习的心态,所以这一节的内容,会比较发散,哪里不懂就探个终究,不感兴趣的能够疏忽,不影响Lifecycle的全体学习。

仍是回忆一下LifecycleRegistry的承继联系以及首要功用函数:

classDiagram
Lifecycle <|-- LifecycleRegistry
class Lifecycle{
    <<Abstract>>
    AtomicReference<Object> mInternalScopeRef
    +addObserver(@NonNull LifecycleObserver observer) void
    +removeObserver(@NonNull LifecycleObserver observer)
    +getCurrentState() State
}
class LifecycleRegistry{
    -State mState
    -FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap
    -WeakReference<LifecycleOwner> mLifecycleOwner
    +handleLifecycleEvent(@NonNull Lifecycle.Event event) void
    +addObserver(@NonNull LifecycleObserver observer) void
    +removeObserver(@NonNull LifecycleObserver observer) void
    +getCurrentState() State
}

LifecycleRegistry作为Lifecycle接口的完结类,能够处理多个调查者,依据接口界说,它有3方面效果:

  • mState特色代表的当时Lifecycle的状况,能够运用getCurrentState()办法来获取状况。
  • 经过调查者模型,运用addObserver()removeObserver()办法来添加和移除调查者,以及处理其间的逻辑。最首要的事务逻辑便是对调查者派产生命周期事情。
  • 经过handleLifecycleEvent()办法来对接ActivityFragment等UI组件,这个在前面咱们说过了,这些组件都是经过该办法来设置Lifecycle的状况。

先来看一下结构函数:

代码段1
//对外的结构函数
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
    this(provider, true);
}
//私有结构函数
private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
    mLifecycleOwner = new WeakReference<>(provider);
    mState = INITIALIZED;
    mEnforceMainThread = enforceMainThread;
}
//生命周期持有者,弱引证封装
private final WeakReference<LifecycleOwner> mLifecycleOwner;
private State mState;
//是否强制主线程
private final boolean mEnforceMainThread;

这儿有个值得学习的点,便是这儿把传递进来的LifecycleOwner用弱引封装起来,即这儿的mLifecycleOwner方针,当运用时需求调用mLifecycleOwner.get()能够获取LifecycleOwner方针。

这儿为什么要运用弱引证呢?由前面可知,这儿的生命周期持有者一般都是ActivityFragment这种重量级的组件类,假设咱们经过getLifecycle()获取的Lifecycle产生了内存走漏,运用弱引证将不会走漏整个ActivityFragment

这儿扩展一下:什么是内存走漏,便是这个类该被GC收回了,发现还被引证则无法被收回,导致内存走漏。就比方获取的lifecycle方针,被过错地传递给了一个全局变量,这时Activity页面封闭,需求被收回,会发现这儿Activity是弱引证,仍旧能够被GC收回。

弱引证效果:当一个类只被弱引证引证时,它也是能够被GC收回的。这个点仍是比较值得咱们平常学习的,防患于未然,假设引证到这种重量级的组件类,能够恰当考虑运用弱引证,以防止内存走漏。

然后便是处理EventhandleLifecycleEvent()办法:

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}

这儿有个值得学习的点,便是怎么判别当时线程是主线程,由于不只仅这个办法,还包含添加/删去调查者都要求在主线程,咱们来看一下:

private void enforceMainThreadIfNeeded(String methodName) {
    if (mEnforceMainThread) {
        if (!ArchTaskExecutor.getInstance().isMainThread()) {
            throw new IllegalStateException("Method " + methodName + " must be called on the "
                    + "main thread");
        }
    }
}
@Override
    public boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }

能够发现这儿是运用Looper来完结的,获取主线程Looper中的线程信息,是否等于当时线程,关于主线程Looper是何时创立和保存线程信息的,等后边有机会介绍Looper时再说。

咱们继续事务剖析,这一行代码moveToState(event.getTargetState())中的getTargetState()办法便是获取当时event希望的状况,这儿合作源码和前面所说的StateEvent联系图十分好了解:

//Event的办法,获取当时event后的状况
public State getTargetState() {
    switch (this) {
        case ON_CREATE:
        case ON_STOP:
            return State.CREATED;
        case ON_START:
        case ON_PAUSE:
            return State.STARTED;
        case ON_RESUME:
            return State.RESUMED;
        case ON_DESTROY:
            return State.DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException(this + " has no target state");
}
Jetpack | Lifecycle全解析

比方Activity派发了ON_CREATE事情给Lifecycle,依据逻辑,当时Lifecycle的希望状况便是CREATED,然后便是moveToState()办法:

代码段2
//切换Lifecycle到next状况
private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    //依据上图可知,状况是无法一次从`INITIALIZED`下降到`DESTROYED`
    if (mState == INITIALIZED && next == DESTROYED) {
        throw new IllegalStateException("no event down from " + mState);
    }
    mState = next;
    //当正在处理Event或许正在添加调查者时,直接return
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        mNewEventOccurred = true;
        return;
    }
    //处理Event的进程
    mHandlingEvent = true;
    sync();
    mHandlingEvent = false;
    //当状况处于DESTROYED时,清空调查者集和
    if (mState == DESTROYED) {
        mObserverMap = new FastSafeIterableMap<>();
    }
}
//是否正在处理事情,即履行`sync()`办法期间
private boolean mHandlingEvent = false;
//是否有新的事情产生
private boolean mNewEventOccurred = false;
//正在添加的调查者有几个
private int mAddingObserverCounter = 0;

这儿代码的flag比较多,其实在日常开发中,为了可读性,代码仍是需求尽量少的运用flag。这儿为什么要运用这么多flag呢?

其实本源便是处理Event的办法和添加/移除调查者都是在主线程上履行的,需求加快履行功率。首要便是一个Lifecycle能够添加多个调查者,由代码可知这些调查者在封装后保存在mObserverMap这个集和中,然后每逢Lifecycle的状况产生改动时,需求告诉这些调查者,这些调查者再去派发事情

而这个进程,便是上面的sync()办法,即表明处理Event进程,这儿的mHandingEvent便是表明是否在这个进程,咱们来看一下该办法:

代码段3
//同步进程,即处理Event的进程
private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    //生命周期持有者可能被收回了
    if (lifecycleOwner == null) {
        throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                + "garbage collected. It is too late to change lifecycle state.");
    }
    //当没有同步完结时
    while (!isSynced()) {
        //进行一次同步
        //由于mState是全局变量,假设有新的Event要处理,这时阐明现已在处理了,
        //所以mNewEventOccourred置为false
        mNewEventOccurred = false;
        //当时状况小于链表最大值,需求降低状况
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            backwardPass(lifecycleOwner);
        }
        //当时状况大于链表最小值,进行前进进步处理
        Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}
//是否是希望的同步完状况
private boolean isSynced() {
        if (mObserverMap.size() == 0) {
            return true;
        }
        //最老调查者的状况
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        //最新调查者状况
        State newestObserverState = mObserverMap.newest().getValue().mState;
        //最老最新状况相同且Lifecycle当时状况等于最新状况
        return eldestObserverState == newestObserverState && mState == newestObserverState;
    }
//保存调查者的集和
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
            new FastSafeIterableMap<>();

上面信息比较多,首要效果便是同步一切调查者的状况,这个什么意思呢?

假设当时Lifecycle有4个调查者,以链表形式保存,每个调查者状况分别为1 -> 1 -> 1 -> 1,依据枚举值,这儿的1便是INITIALIZED状况,这时Lifecycle收到了ON_CREATE事情,依据切换图,这时LifecycleCREATED状况,这时就需求同步4个调查者的状况,告诉调查者的回调函数,需求派发ON_CREATE事情,即把状况变为2 -> 2 -> 2 ->2这样,就算是同步完结。

这儿需求再补充一下保存调查者的集和mObserverMap,这个集和比较特殊,后边详细学习介绍一下,这儿大约说一下,FastSafeIterableMap便是一个简易版的LinkedHashMap,能够在遍历时添加和删去,保存着调查者,可是它有一个不变的特性:在任何时分关于Observer1Observer2来说,假设被Observer1的添加次序小于Observer2的添加次序,那么Observer1的状况要大于等Observer2

这个特性说人话便是这个mObserverMap尽管是个Map,可是添加的Observer是有次序的,任何时分,早添加的值都不小于晚添加的,即这是一个非递加链表

假设有3个调查者,其状况可能是3 -> 2 -> 2,或许3 -> 2 -> 1,绝对不会是2 -> 3 -> 2这种状况。

简略了解完mObserverMap的保存特性后,再来剖析上面同步进程,假设现在有3个调查者,状况分别为2 -> 2 -> 1,这时Lifecycle收到ON_START事情,mState切换为STARTED,这时需求同步3个调查者状况,依据前面代码段3中判别:当时LifecyclemState为3,3比链表最大值2要大,不会履行backwardPass()办法;一同3又比链表最小值1要大,所以需求履行forwardPass()办法:

代码段4
private void forwardPass(LifecycleOwner lifecycleOwner) {
    //获取一个升序遍历迭代器
    Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    //当没有遍历完,且没有新的Event产生        
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        //当时节点
        Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        //当时节点的值
        ObserverWithState observer = entry.getValue();
        //当时节点状况低于mState的状况
        //没有新的Event需求派发
        //当时节点还没有被删去
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            //暂时疏忽    
            pushParentState(observer.mState);
            //进步一级状况,需求派发的Event
            final Event event = Event.upFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + observer.mState);
            }
            //告诉调查者派发Event
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

在了解完mObserverMap非递加特性后,再来看看这段逻辑就十分好了解了,即forward(进步)一切调查者的状况,这儿运用的是升序遍历迭代器,即从大到小进行进步状况,即使被中断了,履行到一半的行列也是契合非递加特性的。每一个调查者自己也需求一个状况,这个待会在添加调查者时细说。

在代码完结中,咱们能够看见有2层while循环,也就阐明这是一个比较耗时的操作,而这也就表现了mNewEventOccurredmHandingEvent的效果了。

咱们来举个比方,假设现有的调查者状况为2,2,1,这时handleLifecycleEvent收到了ON_START事情,这时mState变为3,希望调查者行列同步为3,3,3,此时就需求履行这个耗时的forwardPass()办法,在这期间,mHandingEventtrue。假设这时刚同步到3,2,1状况,又收到了ON_RESUME事情,这时代码段2又被履行了,mState变为4,可是由于前一个同步还没有完结,这时mNewEventOccurred就变成了true,这时forwardPass()会停止履行,回到代码段3中的while循环,从头设置希望的行列为4,4,4,然后再履行forwardPass()办法,依据2层while遍历,把3,2,1进步到4,4,4

由于都是主线程,所以这儿也没有线程安全问题,经过2个变量操控,让本来需求履行屡次的办法,能够就履行一次完结逻辑完结,大大地减缓主线程的压力

forwardPass()对应的办法是backwordPass()办法,从这儿咱们就能够反推出为什么Event中需求规划比方downFrom()downTo()等办法了。

从代码段4中的2个while循环,咱们也能够验证一个定论,便是状况进步和下降都是一步一步履行,是经过事情驱动,即一个调查者状况从CREATED进步到RESUMED,就有必要要派发ON_STARTON_RESUME这2个事情。

咱们继续来看事务逻辑流程,说完了处理LifecycleEvent,来看看怎么添加调查者Observer,以及派发Event

代码段5
public void addObserver(@NonNull LifecycleObserver observer) {
    //强制在主线程
    enforceMainThreadIfNeeded("addObserver");
    //被添加的调查者初始状况
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    //带状况的调查者,把observer进行封装
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    //是否现已被添加过,留意这儿插入Map中的key是observer,value是statefulObserver
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        return;
    }
    //是否从头进入该办法操作,是否重复,即正在添加调查者或许正在处理Event
    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    //核算新添加的observer的希望方针State
    State targetState = calculateTargetState(observer);
    //正在添加的Observer个数加1
    mAddingObserverCounter++;
    //由于初始状况是INITIALIZED,所以只需求进步到方针状况即可
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        //暂时不论    
        pushParentState(statefulObserver.mState);
        //进步状况
        final Event event = Event.upFrom(statefulObserver.mState);
        if (event == null) {
            throw new IllegalStateException("no event up from " + statefulObserver.mState);
        }
        //调查者需求派发事情
        statefulObserver.dispatchEvent(lifecycleOwner, event);
        popParentState();
        //再次核算希望方针State
        targetState = calculateTargetState(observer);
    }
    //在非重复状况下,进行同步
    if (!isReentrance) {
        // we do sync only on the top level.
        sync();
    }
    //进行减1
    mAddingObserverCounter--;
}
//核算一个observer的希望方针State
private State calculateTargetState(LifecycleObserver observer) {
        //获取该observer链表的前一个节点
        Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
        //前一个节点的状况
        State siblingState = previous != null ? previous.getValue().mState : null;
        //获取parentState状况
        State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
                : null;
        //回来最小者        
        return min(min(mState, siblingState), parentState);
    }

addObserver流程比较杂乱,细节较多,咱们先剖析主体事务流程:

  • 首要便是对添加的observer进行封装为ObserverWithState,即把状况和observer封装到一同,正常状况下,状况是初始状况。

  • 然后添加到mObserverMap中,这儿的插入时keyobservervalueObserverWithState

  • isReentrance表明是否重入,这代表什么意思呢?这儿又触及主线程的处理Event和添加调查者操作是否重复,比方刚调用addObserver()办法,还没有履行完,又调用,这时mAddingObserverCounter就不为0,表明添加调查者的操作重复了。

    再比方调用addObserver()时,Lifecycle正在处理事情,这也是阐明2个操作之间重复了。这能够看出在这2种状况下,是不会调用sync()办法的

  • sync()办法是同步一切调查者状况和mState一致以及分发Event,结合这儿的isReentrance和代码段2中的判别条件,咱们能够得出如下定论:

    • 先履行Event处理,没处理完,这时再履行Event处理,操作重复,会直接return掉,前面说了,能够进步履行功率。
    • 先履行Event处理,没处理完,再履行添加调查者,操作重复,判别为重复操作,在进步完新添加的调查者状况后,addObserver()不会进行sync()同步,由于处理Event办法正在同步。
    • 先履行添加调查者,在进步状况时,再履行Event处理,在添加调查者办法中,是不重复操作的,这时能够履行sync(),可是在moveToState()中,mAddingObserverCounter不为空,不会进行重复履行。

    说了这么多,仍是那句话,便是为了让sync()这个办法少履行,以进步主线程履行功率,一同防止同步状况派发事情和添加调查者操作堆叠导致问题

  • 关于新添加的observer需求核算其希望的方针状况,由于链表对错递减的,所以在插入到链表尾后,其方针状况便是前一个节点的状况。

    比方本来链表是3,3,添加进来的原始为1,即为3,3,1,这时经过calculateTargetState()中的ceil()办法就能够得到其希望值为3。

    这儿这种逻辑十分合理,可是为什么calculateTargetState()办法还触及了mParentState变量呢?

    这是一个及其细微的细节,这儿要考虑下面这种极点状况:

    //这是一个调查者,当派发`ON_START`事情时,会触发该回调办法
    void onStart(){
        mRegistry.removeObserver(this)
        mRegistry.add(newObserver)
    }
    

    首要这段代码是在一个Observer中写的,且当时Lifecycle只有this这一个调查者,依据前面咱们所梳理的Lifecycle处理Event流程,当this这个调查者履行onStart()办法时(还没有履行removeObserver),阐明正在派发ON_START事情,这时LifecyclemStateSTARTED状况,调查者行列应该是CREATED -> NULL状况,这是由于在分发Event中,会先回调办法,再改动链表中Observer的状况,代码履行的当地应该是代码段4中的forwardPass()函数部分,即同步状况和派发事情。

    当履行完mRegistry.removeObserver(this)时,依据源码:

@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("removeObserver");
    mObserverMap.remove(observer);
}

能够发现这儿直接会把this从链表中删去,即这时mObserverMap为空的

然后履行mRegistry.add(newObserver),依据前面源码可知需求进步newObserver的状况,j核算进步状况办法为calculateTargetState():

//核算一个observer的希望方针State
private State calculateTargetState(LifecycleObserver observer) {
        //获取该observer链表的前一个节点  1
        Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
        //前一个节点的状况 2
        State siblingState = previous != null ? previous.getValue().mState : null;
        //获取parentState状况 3
        State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
                : null;
        //回来最小者   4     
        return min(min(mState, siblingState), parentState);
    }
static State min(@NonNull State state1, @Nullable State state2) {
        return state2 != null && state2.compareTo(state1) < 0 ? state2 : state1;
    }    

在这种状况下,代码1和2行获取的就会是null,假设没有代码3这一行,经过min函数核算就会回来mState,从前面可知mStateSTARTED状况。

这时就有问题了:thisonStart()办法还没有履行完,在它后边的调查者状况只能小于它,即newObserver被添加进来后,状况应该被进步到CREATED,而不是STARTED

那这时代码行3就有了效果,经过检查代码,咱们能够发现,在履行事情分发的forwardPass()办法中,会记载分发前的状况,然后分发完再移除,经过这个逻辑,代码行3就能够获取现已被删去的this状况:CREATED,这也就契合逻辑了。

剖析完添加调查者后,首要逻辑的处理Event和添加/删去调查者就说完了,咱们来聊一些不是十分重要的知识点。

首要便是前面故意疏忽的添加observer时,对调查者的封装了,调用代码如下:

public void addObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("addObserver");
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ...
}    

这儿的类是ObserverWithState,它封装了调查者,首要效果是持有状况和派发事情(回调事情),类界说如下:

static class ObserverWithState {
    //调查者所持有的状况
    State mState;
    //调查者事情回调函数
    LifecycleEventObserver mLifecycleObserver;
    //结构办法
    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }
    //派发事情
    void dispatchEvent(LifecycleOwner owner, Event event) {
        //该Event的方针State
        State newState = event.getTargetState();
        //取最小值
        mState = min(mState, newState);
        //事务代码履行
        mLifecycleObserver.onStateChanged(owner, event);
        //事务代码履行后,切换到新状况
        mState = newState;
    }
}

这个dispatchEvent()办法中内容的履行次序,在前面解释mParentStates字段效果时说过了,会先进行回调,再设置新的状况

这儿结构函数中,运用Lifecycling中的静态办法,把空办法接口LifecycleObserver经过转化,变成了有办法的一致的LifecycleEventObser类型,这样咱们在dispatchEvent办法中直接运用onStateChanged进行回调即可。

实际上,完结了LifecycleObserver这个空办法接口的类,有3种途径能够收到派发的Event,分别是前面所说过的LifecycleEventObser子类和FullLifecycleObser子类,还有一种办法是经过注解完结的,比方下面调查者:

class CustomObserver : LifecycleObserver{
    //会收到`ON_RESUME`事情时调用该办法
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connectGps(){
        ...
    }
}

在实际写的时分,会发现这种办法现已被废弃了,官方不引荐这种写法,原因也十分简略,这种经过注解生成类的办法,功率比较低,主张运用DefaultLifecycleObserver接口。

还有一个知识点便是用来保存调查者的集和FastSafeIterableMap,它到底和咱们常见的集和有什么特殊之处,咱们来简略剖析剖析。

经过源码注释,咱们知道它其实是一个简易版的LinkedHashMap,在迭代时能够修改增删元素,线程不安全,比较于SafeIterableMap会耗费更多内存,是典型的空间换时间的战略,类图如下:

classDiagram
SafeIterableMap <|-- FastSafeIterableMap
class FastSafeIterableMap{
    -HashMap<K, Entry<K, V>> mHashMap
    ~get(K k) Entry
    ~putIfAbsent(@NonNull K key, @NonNull V v)
    ~remove(@NonNull K key)
    ~contains(K key)
    ~ceil(K k) Entry
}

这儿供给了增删改查的常规API,其实这些功用其父类SafeIterableMap也都完结了,可是该类多了一个mHashMap变量,也便是会耗费更多的内存,而且其API都是基于该mHashMap的:

protected Entry<K, V> get(K k) {
    return mHashMap.get(k);
}
public V putIfAbsent(@NonNull K key, @NonNull V v) {
        Entry<K, V> current = get(key);
        if (current != null) {
            return current.mValue;
        }
        mHashMap.put(key, put(key, v));
        return null;
}   

你或许会疑问这样做的意义是什么呢?便是单纯的为了get()操作更快,这是由于其父类SafeIterableMap看着是一个Map结构,可是真正完结是用链表完结的,而链表这种数据结构,查询是十分慢的

所以咱们就来看看这个用链表伪装成MapSafeIterableMap是怎么完结的。

已然是链表,所以会有头尾节点:

//头节点
Entry<K, V> mStart;
//尾节点
private Entry<K, V> mEnd;
//前后节点
static class Entry<K, V> implements Map.Entry<K, V> {
        @NonNull
        final K mKey;
        @NonNull
        final V mValue;
        Entry<K, V> mNext;
        Entry<K, V> mPrevious;
        ...
    }

这儿便是了解的双向链表节点结构,咱们再来看看增删改查几个API:

//链表尾部添加一个节点
protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
    Entry<K, V> newEntry = new Entry<>(key, v);
    //集和元素个数加一
    mSize++;
    //第一个节点
    if (mEnd == null) {
        mStart = newEntry;
        mEnd = mStart;
        return newEntry;
    }
    //尾插
    mEnd.mNext = newEntry;
    newEntry.mPrevious = mEnd;
    mEnd = newEntry;
    return newEntry;
}
//依据K,找到节点
protected Entry<K, V> get(K k) {
        Entry<K, V> currentNode = mStart;
        //从头开端遍历
        while (currentNode != null) {
            if (currentNode.mKey.equals(k)) {
                break;
            }
            currentNode = currentNode.mNext;
        }
        return currentNode;
}
//删去节点
public V remove(@NonNull K key) {
        //找到待删去的节点
        Entry<K, V> toRemove = get(key);
        if (toRemove == null) {
            return null;
        }
        //个数减一
        mSize--;
        //告诉迭代器,元素被删去了
        if (!mIterators.isEmpty()) {
            for (SupportRemove<K, V> iter : mIterators.keySet()) {
                iter.supportRemove(toRemove);
            }
        }
        //删去的是否是头节点
        if (toRemove.mPrevious != null) {
            toRemove.mPrevious.mNext = toRemove.mNext;
        } else {
            mStart = toRemove.mNext;
        }
        //删去的是否是尾节点
        if (toRemove.mNext != null) {
            toRemove.mNext.mPrevious = toRemove.mPrevious;
        } else {
            mEnd = toRemove.mPrevious;
        }
        toRemove.mNext = null;
        toRemove.mPrevious = null;
        return toRemove.mValue;
    }

看到这儿,你必定会说就这?为什么Google程序员要费力气用链表完结一个Map,还不如运用HashMap呢?

首要它是支撑在非迭代器遍历时进行删去的,不会报ConcurrentModificationException异常,这个特性十分重要,咱们回忆一下,LifecycleRegistry在处理EventaddObserver()后都有一个十分要害的步骤,便是同步,而且说了要害的sync()函数是不会在这2个动作穿插、重复的状况下履行,可是移除调查者的removeObserver()办法却没有任何限制。也便是说彻底能够在任何时分进行删去调查者,甚至在遍历的时分,这儿不出错,便是该链表的效果。

还有一个特色便是供给了正序和反序的迭代器,关于HashMap来说咱们是无法操控其遍历次序是否和添加次序相同的,再结合事务剖析,前面咱们说了observerMap中保存的调查者,对错递加的,即值和添加次序有关,而且改动链表中的值也不能打破这个规矩,所以正序和反序遍历就十分有必要。

话不多说,来看源码:

//Iterable接口完结办法,可用于快速遍历
//在迭代期间,不会包含新添加的元素
public Iterator<Map.Entry<K, V>> iterator() {
        //回来一个正序迭代器 
        ListIterator<K, V> iterator = new AscendingIterator<>(mStart, mEnd);
        //添加到迭代器行列中
        mIterators.put(iterator, false);
        return iterator;
}
//回来一个反序迭代器,同样在迭代期间,是无法保护新添加的元素
public Iterator<Map.Entry<K, V>> descendingIterator() {
        DescendingIterator<K, V> iterator = new DescendingIterator<>(mEnd, mStart);
        mIterators.put(iterator, false);
        return iterator;
}
//回来一个正序迭代器,能够在迭代期间添加新元素,且能够迭代到
public IteratorWithAdditions iteratorWithAdditions() {
        IteratorWithAdditions iterator = new IteratorWithAdditions();
        mIterators.put(iterator, false);
        return iterator;
}
//保存迭代器的集和
private WeakHashMap<SupportRemove<K, V>, Boolean> mIterators = new WeakHashMap<>();

这儿供给了3种迭代器,这3种迭代器都支撑在迭代时删去元素,其间iterator()descendingIterator()回来的迭代器是ListIterator的子类,经过传入头尾节点来进行迭代,所以在迭代中对新添加的元素是无法感知的。

关于iteratorWithAdditions()回来的迭代器,是正序迭代,且能够感知遍历到在遍历中添加的元素。至于这3个迭代器的完结,咱们就不看细节了,无外乎便是链表操作。

这儿看一个值得学习的点,便是这个mIterators数据类型:WeakHashMap

在文章前面介绍Lifecycle原理是时也说到了弱引证,那是用来防止内存走漏的。而这儿的WeakHashMap则是用来节省内存,简化操作的WeakHashMap对存放的键值对的Key(键)做了弱引证处理,当某个键值对没有强引证时,能够主动被移除,然后被GC收回。

假设这儿存在屡次调用迭代器的状况,尽管每次都把迭代器放进了mIterators,可是它的内存占用不会继续添加,会在恰当时分释放这些迭代器方针的内存。至于为什么要保存这些迭代器,能够看一下上面remove()操作,在remove()时需求告诉迭代器,这也是这些迭代器支撑删去的原因。

ProcessLifecycleOwner解析

前面所说的都是以ActivityFragment作为生命周期持有者的状况,其实还有一种常见的状况,便是以app运用作为生命周期持有者,也便是这儿的ProcessLifecycleOwner进程生命周期持有者

运用如下:

//在App的OnCreate()办法中写如下代码
//Observer接口好几种写法,按需求挑选
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver{
    //只会派发一次
    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        Logger.t("BaseApp").d("onCreate")
    }
    //当APP可见时派发
    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        Logger.t("BaseApp").d("onStart")
    }
    //当APP能够交互时派发,这时APP处于前台
    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
        Logger.t("BaseApp").d("onResume")
    }
    //当APP不行交互时派发,即退出到后台
    override fun onPause(owner: LifecycleOwner) {
        super.onPause(owner)
        Logger.t("BaseApp").d("onPause")
    }
    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
        Logger.t("BaseApp").d("onStop")
    }
    //永久不会被派发
    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        Logger.t("BaseApp").d("onDestroy")
    }
})

上面的运用中,首要适用于一个场景:有些APP需求在退到后台时,需求提示弹出Toast,比方一些银行APP。而且需求留意上面各种事情的派发次数。

老规矩,咱们仍是来看看这个整个运用的生命周期持有者是怎么派发这些事情的。

首要一个APP正常来说就一个Application运用,所以这儿ProcessLifecycleOwner应该坚持单例:

public static LifecycleOwner get() {
    return sInstance;
}
private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();
private ProcessLifecycleOwner() { }

这儿运用静态办法由JVM完结的单例,可是咱们居然发现其结构函数居然是空的,那什么当地开端逻辑事务的呢?

这儿就用到了一个小知识点,运用ContentProvider来发动初始化逻辑,这种用法在许多开源库都有运用,这儿咱们在XML中找到如下代码:

<application>
    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge" >
        <meta-data
            android:name="androidx.lifecycle.ProcessLifecycleInitializer"
            android:value="androidx.startup" />
    </provider>
</application>

这儿的InitializationProvider承继至ContentProvider,能够用来初始化一些app的信息,而且会在Application.onCreate()之前进行调用。

这儿触及startup库的运用,咱们只需求知道,这儿的初始化器是界说在meta-data中的ProcessLifecycleInitializer:

public final class ProcessLifecycleInitializer implements Initializer<LifecycleOwner> {
    //初始化的实例
    @NonNull
    @Override
    public LifecycleOwner create(@NonNull Context context) {
        //给每一个Activity都hook一个ReportFragment
        LifecycleDispatcher.init(context);
        //初始化事务
        ProcessLifecycleOwner.init(context);
        return ProcessLifecycleOwner.get();
    }
    //所依靠的类
    @NonNull
    @Override
    public List<Class<? extends Initializer<?>>> dependencies() {
        return Collections.emptyList();
    }
}

这样逻辑才对,运用ContentProvider咱们能够保证在Application.onCreate()之前就开端初始化逻辑,咱们来看看init()办法的逻辑:

static void init(Context context) {
    sInstance.attach(context);
}
void attach(Context context) {
        //主线程Handler
        mHandler = new Handler();
        //仍旧是Registry来做事情分发
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        //注册Activity的事情回调
        app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
            @RequiresApi(29)
            @Override
            public void onActivityPreCreated(@NonNull Activity activity,
                    @Nullable Bundle savedInstanceState) {
                activity.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
                    @Override
                    public void onActivityPostStarted(@NonNull Activity activity) {
                        //有activity触发到onStarted()
                        activityStarted();
                    }
                    @Override
                    public void onActivityPostResumed(@NonNull Activity activity) {
                        //有activity触发onResumed()
                        activityResumed();
                    }
                });
            }
             ...
            @Override
            public void onActivityPaused(Activity activity) {
                //触发onPause
                activityPaused();
            }
            @Override
            public void onActivityStopped(Activity activity) {
                //触发onStop
                activityStopped();
            }
        });
    }

思路十分简略,每逢一个Activity回调其生命周期函数时,进行记载,这种逻辑在之前咱们经常在BaseActivity中写,来完结相似功用。

具体几个办法都比较简略,这儿咱们就不做源码的复制粘贴了,便是经过2个变量mStartedCountermResumedCounter来记载有多少Activity发动和毁掉,当为0时就阐明APP退到后台

可是这儿完结了一个特殊场景判别,即当运用产生配置改动,比方旋转,这时生命周期会从头回调,假设只是判别数量的话,会导致旋转时也会以为是进入到后台。

为了解决这个问题,源码中加了延迟处理以及mPauseSent等字段来加以判别,去除这种状况。

总结

不知不觉现已写了一万多字了,不得不说,这种优异的库的源码便是一座宝藏,看源码的进程真的是一个继续学习的进程,不只仅能够加深了解,更能够学习规划思路、完结思路和办法等。

仍是做个总结吧,如下:

  • 当人们面临杂乱的的问题,一个有用的办法是分层和笼统,所以Lifecycle便是为了一致生命周期,供给一些公共的特色和办法,便利开发者对接。
Jetpack | Lifecycle全解析
  • 在根本运用前,咱们运用UML类图来给出了要害类的联系,合理运用UML类图有利于快速构建联系。

  • 在根本用法中,咱们简略介绍了几种运用,包含:

    • 监听Lifecycle所派发的生命周期事情;
    • 获取当时Lifecycle状况;
    • 依据别离关注点思维来简化代码,把逻辑从散落在生命周期函数中的逻辑给会集一同;
    • 还有便是架构和事务别离,合理运用能够防备内存走漏,比方合作协程、Handler、Dialog等。
  • 在Lifecycle解析部分中,咱们首要介绍了其间的State和Event,这儿需求深刻了解该图:

Jetpack | Lifecycle全解析

结合图中示意,了解每个State的意义,以及要害的的downFromupFrom等办法规划思路和意义。

  • 这儿咱们一向秉承一个思维便是事情驱动状况改动LifecycleOwner完结类比方Activity,派发Event驱动Lifecycle的状况改动,Lifecycle再派发事情,改动其调查者状况,一同状况改动不能跨级,只能一步一步改动。
  • Lifecycle原了解析部分,先是剖析了最常见的组件Activity是在时分派发Event的,这部分咱们触及了ReportFragment的运用和介绍,这种奇妙运用ActivityFragment联系的办法,能够看成是一种hook,来获取Activity生命周期回调。
  • 完结LifecycleOwner的核心是能够正确、合理派发EventLifecycleRegistry
  • 在剖析Fragment派发Event中可知,有2个LifecycleOwner,一个是Fragment自己的,一个是其View的,经过剖析调用链联系,咱们可得如下图:
Jetpack | Lifecycle全解析
  • 经过该图咱们需求愈加了解EventState的联系,以及和对应生命周期函数调用的先后联系。一同剖析了在Fragment中运用viewlifecycle来替代lifecycle的原因,便是在旧Fragment入栈出栈,会导致重复添加调查者。

  • LifecycleRegistry原理部分就比较随意了,是坚持学习心态来探求的,它是官方供给的Lifecycle接口的完结类,能够处理多个调查者。

    • 在结构函数有个值得学习借鉴的点,便是把Activity或许Fragment运用弱引证封装,这种能够有用防止这种重量级的组件产生内存走漏。
    • 在派发事情中,由于要处理多个调查者状况同步和派发,所以这儿运用mHandingEventmNewEventOccurred这2个flag能防止屡次履行,加快功率。
    • 在派发事情和添加调查者这2个都是在主线程调用的函数,为了防止出错和功率,这儿经过多个flag来保证sync()办法只会运行在非嵌套动作的状况下。
    • 其次咱们学习了SafeIterableMap这个数据接口,一同在LifecycleRegistry中它一向坚持非递加的规矩,实际上它是由链表完结的Map,支撑在遍历时删去和添加。
  • 最后便是ProcessLifecycleOwner的介绍,首要用于完结app处于前台、后台判别的需求,一同该库运用ContentProvider是保证在ApplicationonCreate()之前进行初始化。