在我最近編寫的項(xiàng)目中癌蚁,始終貫穿整個(gè)事件流的組件,可能就是LifeCycle了戳寸,在我眼里呈驶,它就像是個(gè)通用化的UI生命周期管理對(duì)象,在Android View層的生命周期方法被調(diào)用時(shí)疫鹊,它可以給所有注冊(cè)過(guò)它的方法發(fā)送生命周期事件袖瞻,然后由你決定是否進(jìn)行處理。
那么問(wèn)題來(lái)了拆吆,這不就是接口+觀察者模式就可以實(shí)現(xiàn)么虏辫?那樣它看起來(lái)并不像它本身那么酷啊。
話不多說(shuō)锈拨,先上使用場(chǎng)景
例子1 來(lái)自我們經(jīng)典的sunflower
// GalleryFragment.kt
private fun search(query: String) {
// Make sure we cancel the previous job before creating a new one
searchJob?.cancel()
searchJob = lifecycleScope.launch { // 這里可以看成是綁定了View生命周期的線程,一旦View生命停止羹唠,它也將被釋放
viewModel.searchPictures(query).collectLatest { // 執(zhí)行的任務(wù)
adapter.submitData(it)
}
}
}
可能你會(huì)特別蒙蔽奕枢,不急娄昆,我們直接 進(jìn)入lifecycleScope中看看
// LifecycleOwner.kt
val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope get() = lifecycle.coroutineScope
// 上面又是kotlin無(wú)比裝逼的寫法 但是可以看出來(lái) 返回的是LifecycleCoroutineScope
// Lifecycle.kt
val Lifecycle.coroutineScope: LifecycleCoroutineScope // ok 返回的就是我了
get() {
while (true) {
val existing = mInternalScopeRef.get() as LifecycleCoroutineScopeImpl?
if (existing != null) {
return existing
}
val newScope = LifecycleCoroutineScopeImpl( // 如果沒(méi)有這個(gè)任務(wù) 就新建任務(wù)
this,
SupervisorJob() + Dispatchers.Main.immediate
)
if (mInternalScopeRef.compareAndSet(null, newScope)) { // 這個(gè)方法 CAS 蕪湖, 把新加的注冊(cè)進(jìn)列表
newScope.register()
return newScope
}
}
}
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@NonNull
AtomicReference<Object> mInternalScopeRef = new AtomicReference<>(); // 看到這個(gè)Java老哥不會(huì)陌生了把缝彬,CAS原子操作 看到它就會(huì)不自然的想到unsafe =萌焰。= (老面試哥的職業(yè)病)
internal class LifecycleCoroutineScopeImpl( // 由我來(lái)實(shí)現(xiàn) 協(xié)程(還是想吐槽谷浅,攜程是不是給了kotlin廣告費(fèi))+ View的生命周期綁定
override val lifecycle: Lifecycle,
override val coroutineContext: CoroutineContext
) : LifecycleCoroutineScope(), LifecycleEventObserver {
init {
// in case we are initialized on a non-main thread, make a best effort check before
// we return the scope. This is not sync but if developer is launching on a non-main
// dispatcher, they cannot be 100% sure anyways.
if (lifecycle.currentState == Lifecycle.State.DESTROYED) { // 生命周期被銷毀
coroutineContext.cancel() // 協(xié)程取消
}
}
fun register() {
launch(Dispatchers.Main.immediate) {
if (lifecycle.currentState >= Lifecycle.State.INITIALIZED) {
lifecycle.addObserver(this@LifecycleCoroutineScopeImpl)
} else {
coroutineContext.cancel()
}
}
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (lifecycle.currentState <= Lifecycle.State.DESTROYED) {
lifecycle.removeObserver(this)
coroutineContext.cancel()
}
}
}
上面就是LifeCycle在協(xié)程生命周期上的管理體現(xiàn)(google你為什么不早不做扒俯,想起了當(dāng)年被生命周期支配的恐懼)
例子2:來(lái)自自己的項(xiàng)目
首先要說(shuō)明一下,Android在RxJava + RxAndroid的使用中一疯,內(nèi)存泄漏是很常見的問(wèn)題撼玄,因?yàn)楫惒饺蝿?wù)本身是不會(huì)去感知你View的生命周期的,我自己項(xiàng)目中使用的是autoDispose
三方框架實(shí)現(xiàn)了RxJava墩邀、RxAndroid任務(wù)對(duì)LifeCycle的綁定
// 登錄請(qǐng)求
RxView.clicks(mDataBinding.loginBtn)
.subscribeOn(AndroidSchedulers.mainThread())
.to(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this))) // 沒(méi)錯(cuò)就是我 我綁定了LifecycleOwner
.subscribe(unit ->
PermissionTools.requestPermission(this, () -> // 校驗(yàn)讀寫權(quán)限
mViewModel.Login(mDataBinding.userNameEdt.getText().toString().trim() // 登錄請(qǐng)求
, mDataBinding.passwordEdt.getText().toString().trim())
, Permission.READ_PHONE_STATE));
// 登錄信息返回通知
LiveEventBus.get(RequestTags.LOGIN_REQ, BaseResponBean.class)
.observe(this, bean -> { // 我也綁定了LifecycleOwner
Optional.ofNullable(mLoading).ifPresent(builder -> mLoading.getObj().dismiss()); // 取消 Loading
if (bean.getCode() == 200) { // 登錄成功
ToastUtil.showToast(LoginActivity.this, "登錄成功掌猛!");
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();
} else { // 登錄失敗
ToastUtil.showToast(LoginActivity.this, "登錄失敗:" + TCErrorConstants.getErrorInfo(bean.getCode()));
mDataBinding.passwordEdt.setText(""); // 清空密碼輸入框
}
});
以上就是兩個(gè)十分簡(jiǎn)單的LifeCycle的實(shí)際運(yùn)用,下面分析一下LifeCycle到底做了些什么眉睹。
我們通過(guò)AppCompatActivity找到他的父類荔茬,F(xiàn)ragmentActivity的父類, ComponentActivity
//LifecycleOwner.java
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
//ComponentActivity.java
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry; // 我返回的就是LifeCycle
}
......
}
//LifecycleRegistry.java 這算是核心類了
public class LifecycleRegistry extends Lifecycle {
//FastSafeIterableMap 它最重要的特點(diǎn)就是竹海,支持在遍歷的過(guò)程中刪除任意元素慕蔚,不會(huì)觸發(fā)ConcurrentModifiedException
//自然 它也無(wú)法保證線程安全 這個(gè)對(duì)象是以模擬Map的形式,存了訂閱者key斋配,以及訂閱者的狀態(tài)value
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
//你可以泄漏我Lifecycle 但是你沒(méi)法泄漏LifecycleOwner
private final WeakReference<LifecycleOwner> mLifecycleOwner;
/**
* Current state
*/
private State mState; // 這個(gè)就不用說(shuō)了吧
// 更新狀態(tài)
@MainThread
public void setCurrentState(@NonNull State state) {
moveToState(state);
}
// 開始更新
private void moveToState(State next) {
if (mState == next) { // 重復(fù)事件 丟棄
return;
}
mState = next; // 本地事件狀態(tài)更新
if (mHandlingEvent || mAddingObserverCounter != 0) { // 如果上一次同步?jīng)]有進(jìn)行完 或 表示正在同步新訂閱者的數(shù)量為0 就不處理了
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true; // 開始同步
sync();
mHandlingEvent = false; // 同步結(jié)束
}
// 同步所有觀察者
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()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner); // 每次同步只向低等級(jí)移動(dòng)
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner); // 每次同步向高等級(jí)移動(dòng)
}
}
mNewEventOccurred = false;
}
// 判斷是否以及全部同步完成
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
}
看圖說(shuō)話 backwardPass 就是RESUMED 到 DESTROYED 的過(guò)程孔飒,每次只能變化一次,連續(xù)的動(dòng)作
forwardPass就是INITIALIZED 到 RESUMED 的過(guò)程许起,同樣 每次只能變化一次十偶, 連續(xù)的動(dòng)作
這時(shí)候問(wèn)題就來(lái)了,為什么要這么做园细? 而且那個(gè)嵌套的判斷如何解決在同步的過(guò)程中有新的觀察者加入的情況
這是可以細(xì)化成兩個(gè)小點(diǎn)
在同步過(guò)程中惦积,加入了新觀察者
在同步過(guò)程中,新狀態(tài)更變加入
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) { // 中斷機(jī)制猛频,如果有新的狀態(tài)更變或是訂閱者出現(xiàn)狮崩,上一次同步會(huì)被中斷
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState); // 入棧
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); // 回調(diào)通知狀態(tài)更變
popParentState(); // 出棧
}
}
}
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
while (descendingIterator.hasNext() && !mNewEventOccurred) {// 中斷機(jī)制,如果有新的狀態(tài)更變或是訂閱者出現(xiàn)鹿寻,上一次同步會(huì)被中斷
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = downEvent(observer.mState);
pushParentState(getStateAfter(event));
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
這里又出現(xiàn)了個(gè)pushParentState以及popParentState 這個(gè)棧又是為了保證什么的呢
為了保證新增的狀態(tài)不會(huì)破壞整個(gè)Map的有序性
這時(shí)候你會(huì)覺得奇怪睦柴,有序性?什么有序性
仔細(xì)看一下sync就會(huì)明白毡熏,同步的判斷依賴于新加入的訂閱者狀態(tài)肯定新于之前加入的訂閱者
private State calculateTargetState(LifecycleObserver observer) {
Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
//previous代表訂閱者的當(dāng)前狀態(tài)
State siblingState = previous != null ? previous.getValue().mState : null;
//在出現(xiàn)事件嵌套時(shí)坦敌,棧內(nèi)不為空,最后加入的那個(gè)狀態(tài),肯定是最新的狀態(tài)
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
//mParentStates狱窘,它限制了新的訂閱者的狀態(tài)更新晚于前面的訂閱者
return min(min(mState, siblingState), parentState);
}
這應(yīng)該算是犧牲一部分性能保證有序性的操作
以上就是Lifecycle一次狀態(tài)更變的大致流程杜顺,看起來(lái)確實(shí)也沒(méi)有太多東西,一個(gè)觀察者模式蘸炸,一套新規(guī)則躬络,解決了長(zhǎng)年的生命周期管理問(wèn)題,看來(lái)基于業(yè)務(wù)的開發(fā)才是未來(lái)的主流