本文正在参与「金石计划 . 分割6万现金大奖」
前言
咱们都知道Activity
与Fragment
都是有生命周期的,例如:onCreate()
、onStop()
这些回调办法就代表着其生命周期状况。咱们开发者所做的一些操作都应该合理的操控在生命周期内,比方:当咱们在某个Activity
中注册了播送接收器,那么在其onDestory()
前要记住刊出掉,避免呈现内存走漏。
生命周期的存在,帮助咱们愈加方便地办理这些使命。但是,在日常开发中光凭 Activity
与Fragment
可不行,咱们通常还会运用一些组件来帮助咱们完成需求,而这些组件就不像Activity
与Fragment
相同能够很方便地感知到生命周期了。
假定当时有这么一个需求:
开发一个简易的视频播映器组件以供项目运用,要求在进入页面后注册播映器并加载资源,一旦播映器所在的页面不行见或许不坐落前台时就暂停播映,等到页面可见或许又恢复到前台时再继续播映,最终在页面毁掉时则刊出掉播映器。
试想一下:假如现在让你来完成该需求?你会怎样去完成呢?
完成这样的需求,咱们的播映器组件就需要获取到所在页面的生命周期状况,在onCreate()
中进行注册,onResume()
开端播映,onStop()
暂停播映,onDestroy()
刊出播映器。
最简单的办法:供给办法,露出给运用方,供其自己调用操控。
class VideoPlayerComponent(private val context: Context) {
/**
* 注册,加载资源
*/
fun register() {
loadResource(context)
}
/**
* 刊出,开释资源
*/
fun unRegister() {
releaseResource()
}
/**
* 开端播映当时视频资源
*/
fun startPlay() {
startPlayVideo()
}
/**
* 暂停播映
*/
fun stopPlay() {
stopPlayVideo()
}
}
然后,咱们的运用方MainActivity自己,自动在其相对应的生命周期状况进行操控调用相对应的办法。
class MainActivity : AppCompatActivity() {
private lateinit var videoPlayerComponent: VideoPlayerComponent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
videoPlayerComponent = VideoPlayerComponent(this)
videoPlayerComponent.register(this)
}
override fun onResume() {
super.onResume()
videoPlayerComponent.startPlay()
}
override fun onPause() {
super.onPause()
videoPlayerComponent.stopPlay()
}
override fun onDestroy() {
videoPlayerComponent.unRegister()
super.onDestroy()
}
}
尽管完成了需求,但显然这不是最优雅的完成办法。一旦运用方忘掉在onDestroy()
进行刊出播映器,就容易造成内存走漏,而忘掉刊出显然是一件很容易发生的工作。
回想初衷,之所以将办法露出给运用方来调用,便是因为咱们的组件本身无法感知到运用者的生命周期。所以,一旦咱们的组件本身能够感知到运用者的生命周期状况的话,咱们就不需要将这些办法露出出去了。
那么问题来了,组件怎么才干感知到生命周期呢?
答:Lifecycle
!
直接上案例,借助 Lifecycle
咱们改进一下咱们的播映器组件
class VideoPlayerComponent(private val context: Context) : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
register(context)
}
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
startPlay()
}
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
stopPlay()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
unRegister()
}
/**
* 注册,加载资源
*/
private fun register(context: Context) {
loadResource(context)
}
/**
* 刊出,开释资源
*/
private fun unRegister() {
releaseResource()
}
/**
* 开端播映当时视频资源
*/
private fun startPlay() {
startPlayVideo()
}
/**
* 暂停播映
*/
private fun stopPlay() {
stopPlayVideo()
}
}
改进完成后,咱们的调用方MainActivity只需要一行代码即可。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
lifecycle.addObserver(VideoPlayerComponent(this))
}
}
这样是不是就优雅多了。
那这 Lifecycle
又是怎样感知到生命周期的呢?让咱们这就带着问题,动身探一探它的完成办法与源码!
假如让你来做,你会怎样做
在检查源码前,让咱们试着考虑一下,假如让你来完成Jetpack Lifecycle
这样的功用,你会怎样做呢?该从何入手呢?
咱们的意图是不通过回调办法即可获取到生命周期,这其实便是解耦,完成解耦的一种很好办法便是利用调查者形式。
利用调查者形式,咱们就能够这么规划
被调查者目标便是生命周期,而调查者目标则是需要知晓生命周期的目标,例如:咱们的三方组件。
接着咱们就详细探探源码,看一看Google是怎么完成的吧。
Google 完成办法
Lifecycle
一个代表着Android生命周期的笼统类,也便是咱们的笼统被调查者目标。
public abstract class Lifecycle {
public abstract void addObserver(@NonNull LifecycleObserver observer);
public abstract void removeObserver(@NonNull LifecycleObserver observer);
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY;
}
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
}
}
内包括State
与Event
分别者代表生命周期的状况与事情,一同定义了笼统办法addObserver(LifecycleObserver)
与removeObserver(LifecycleObserver)
办法用于增加与删去生命周期调查者。
Event
很好了解,就像是Activity | Fragment
的onCreate()
、onDestroy()
等回调办法,它代表着生命周期的事情。
那这State
又是什么呢?何为状况?他们之间又是什么联络呢?
Event 与 State 之间的联络
关于Event
与State
之间的联络,Google官方给出了这么一张两者联络图
乍一看,或许第一感觉不是那么直观,我整理了一下
-
INITIALIZED
:在ON_CREATE
事情触发前。 -
CREATED
:在ON_CREATE
事情触发后以及ON_START
事情触发前;或许在ON_STOP
事情触发后以及ON_DESTROY
事情触发前。 -
STARTED
:在ON_START
事情触发后以及ON_RESUME
事情触发前;或许在ON_PAUSE
事情触发后以及ON_STOP
事情触发前。 -
RESUMED
:在ON_RESUME
事情触发后以及ON_PAUSE
事情触发前。 -
DESTROYED
:在ON_DESTROY
事情触发之后。
Event
代表生命周期发生变化那个瞬间点,而State
则表示生命周期的一个阶段。这两者结合的好处便是让咱们能够愈加直观的感触生命周期,然后能够依据当时所在的生命周期状况来做出愈加合理操作行为。
例如,在LiveData
的生命周期绑定调查者源码中,就会判别当时调查者目标的生命周期状况,假如当时是DESTROYED
状况,则直接移除当时调查者目标。一同,依据调查者目标当时的生命周期状况是否>= STARTED
来判别当时调查者目标是否是活泼的。
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
......
@Override
boolean shouldBeActive() {
//依据调查者目标当时的生命周期状况是否 >= STARTED 来判别当时调查者目标是否是活泼的。
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//依据当时调查者目标的生命周期状况,假如是DESTROYED,直接移除当时调查者
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
......
}
......
}
其实Event
与State
这两者之间的联络,在咱们生活中也是处处可见,例如:自动洗车。
想必现在你对Event
与State
之间的联络有了更好的了解了吧。
LifecycleObserver
生命周期调查者,也便是咱们的笼统调查者目标。
public interface LifecycleObserver {
}
所以,咱们想成为调查生命周期的调查者的话,就需要详细完成该接口,也便是成为详细调查者目标。
换句话说,便是假如你想成为调查者目标来调查生命周期的话,那就必须完成 LifecycleObserver
接口。
例如Google官方供给的 DefaultLifecycleObserver
、LifecycleEventObserver
。
LifecycleOwner
正如其姓名相同,生命周期的持有者,所以像咱们的 Activity | Fragment
都是生命周期的持有者。
大白话很好了解,但代码应该怎么完成呢?
笼统概念 + 详细完成
笼统概念:定义 LifecycleOwner
接口。
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
详细完成:Fragment
完成 LifecycleOwner
接口。
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner,
ActivityResultCaller {
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
......
}
详细完成:Activity
完成 LifecycleOwner
接口。
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
ActivityResultCaller {
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
......
}
这样,Activity | Fragment
就都是生命周期持有者了。
疑问?在上方 Activity | Fragment
的类中,getLifecycle()
办法中都是回来mLifecycleRegistry
,那这个 mLifecycleRegistry
又是什么玩意呢?
LifecycleRegistry
是
Lifecycle
的一个详细完成类。
LifecycleRegistry
负责办理生命周期调查者目标,并将最新的生命周期事情与状况及时通知给对应的生命周期调查者目标。
增加与删去调查者目标的详细完成办法。
//用户保存生命周期调查者目标
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//将生命周期调查者目标包装成带生命周期状况的调查者目标
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
... 省掉代码 ...
}
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
mObserverMap.remove(observer);
}
能够从上述代码中发现,LifecycleRegistry 还对生命周期调查者目标进行了包装,使其带有生命周期状况。
static class ObserverWithState {
//生命周期状况
State mState;
//生命周期调查者目标
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//这里确保observer为LifecycleEventObserver类型
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
//并初始化了状况
mState = initialState;
}
//分发事情
void dispatchEvent(LifecycleOwner owner, Event event) {
//依据 Event 得出当时最新的 State 状况
State newState = event.getTargetState();
mState = min(mState, newState);
//触发调查者目标的 onStateChanged() 办法
mLifecycleObserver.onStateChanged(owner, event);
//更新状况
mState = newState;
}
}
将最新的生命周期事情通知给对应的调查者目标。
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
... 省掉代码 ...
ObserverWithState observer = mObserverMap.entrySet().getValue();
observer.dispatchEvent(lifecycleOwner, event);
... 省掉代码 ...
mLifecycleObserver.onStateChanged(owner, event);
}
那handleLifecycleEvent()
办法在什么时候被调用呢?
相信看到下方这个代码,你就理解了。
public class FragmentActivity extends ComponentActivity {
......
final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
@Override
protected void onDestroy() {
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
@Override
protected void onPause() {
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
@Override
protected void onStop() {
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
......
}
在Activity | Fragment
的onCreate()
、onStart()
、onPause()
等生命周期办法中,调用LifecycleRegistry
的handleLifecycleEvent()
办法,然后将生命周期事情通知给调查者目标。
总结
Lifecycle
通过调查者规划形式,将生命周期感知目标与生命周期供给者充分解耦,不再需要通过回调办法来感知生命周期的状况,使代码变得愈加的精简。
尽管不通过Lifecycle
,咱们的组件也是能够获取到生命周期的,但是Lifecycle
的含义便是供给了统一的调用接口,让咱们的组件能够愈加方便的感知到生命周期,方便广达开发者。并且,Google以此推出了更多的生命周期感知型组件,例如:ViewModel
、LiveData
。正是这些组件,让咱们的开发变得越来越简单。
相关文章推荐阅读:
- 关于ViewModel的这几个问题,你都知道吗?
- 为什么Google要将LiveData规划成粘性的
- 为什么LiveData的调查者必须处于主线程中
到此本篇文章就完毕啦,假如你有任何疑问或许不同的想法,欢迎在评论区留言与我一同探讨。
其实共享文章的最大意图正是等待着有人指出我的过错,假如你发现哪里有过错,请毫无保留的指出即可,谦虚讨教。
别的,假如你觉得文章不错,对你有所帮助,请帮我点个赞,就当鼓励,谢谢~