Jetpack AAC 系列文章:
“終于懂了“系列:Jetpack AAC完整解析(一)Lifecycle 完全掌握!
“終于懂了“系列:Jetpack AAC完整解析(二)LiveData 完全掌握!
“終于懂了“系列:Jetpack AAC完整解析(三)ViewModel 完全掌握!
一、Android Jetpack 介紹
1.1 Jetpack是啥
官方定義如下:
Jetpack 是一個(gè)由多個(gè)庫(kù)組成的套件,可幫助開(kāi)發(fā)者遵循最佳做法,減少樣板代碼并編寫(xiě)可在各種 Android 版本和設(shè)備中一致運(yùn)行的代碼,讓開(kāi)發(fā)者精力集中編寫(xiě)重要的代碼。
JetPack更多是一種概念和態(tài)度,它是谷歌開(kāi)發(fā)的非Android Framework SDK自帶、但同時(shí)是Android開(kāi)發(fā)必備的/推薦的SDK/開(kāi)發(fā)規(guī)范合集。相當(dāng)于Google把自己的Android生態(tài)重新整理了一番,確立了Android未來(lái)的開(kāi)發(fā)大方向。
使用Jetpack有如下好處:
- 遵循最佳做法,Android Jetpack 組件采用最新的設(shè)計(jì)方法構(gòu)建,具有向后兼容性,可以減少崩潰和內(nèi)存泄露。
- 消除樣板代碼,Android Jetpack 可以管理各種繁瑣的 Activity(如后臺(tái)任務(wù)、導(dǎo)航和生命周期管理),以便您可以專(zhuān)注于打造出色的應(yīng)用。
- 減少不一致,這些庫(kù)可在各種 Android 版本和設(shè)備中以一致的方式運(yùn)作,助您降低復(fù)雜性。
Jetpack原意為 噴氣背包,Android背上Jetpack后就直沖云霄,這很形象了~
也就是,Jetpack是幫助開(kāi)發(fā)者高效開(kāi)發(fā)應(yīng)用的工具集。那么這一工具包含了哪些內(nèi)容呢?
1.2 Jetpack分類(lèi)
分類(lèi)如下圖(現(xiàn)在官網(wǎng)已經(jīng)找不到這個(gè)圖了):
Android Jetpack 組件覆蓋以下 4 個(gè)方面:架構(gòu)(Architecture)、基礎(chǔ)(Foundation)、行為(Behavior) 、界面(UI)。
真正的精華主要是Architecture,全稱(chēng)是Android Architecture Component(AAC), 即Android架構(gòu)組件。
其包括比較成功的Lifecycle、LiveData、ViewModel,同時(shí)也是我們使用MVVM模式的最好框架工具,可以組合使用,也可以單獨(dú)使用。
以上基本都是官網(wǎng)的介紹,我們主要目標(biāo)就是掌握AAC的組件,深入理解進(jìn)而運(yùn)用到MVVM架構(gòu)中。
如題,我們學(xué)習(xí)Jetpack的重點(diǎn)就是AAC,這篇就從基礎(chǔ)的Lifecycle講起。
二、Lifecycle
Lifecycle,顧名思義,是用于幫助開(kāi)發(fā)者管理Activity和Fragment 的生命周期,它是LiveData和ViewModel的基礎(chǔ)。下面就先介紹為何及如何使用Lifecycle。
2.1 Lifecycle之前
官方文檔有個(gè)例子 來(lái)說(shuō)明使用Lifecycle之前是如何生命周期管理的:
假設(shè)我們有一個(gè)在屏幕上顯示設(shè)備位置的 Activity。常見(jiàn)的實(shí)現(xiàn)可能如下所示:
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// 連接系統(tǒng)定位服務(wù)
}
void stop() {
// 斷開(kāi)系統(tǒng)定位服務(wù)
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
}
@Override
public void onStart() {
super.onStart();
myLocationListener.start();
// 管理其他需要響應(yīng)activity生命周期的組件
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
// 管理其他需要響應(yīng)activity生命周期的組件
}
}
雖然此示例看起來(lái)沒(méi)問(wèn)題,但在真實(shí)的應(yīng)用中,最終會(huì)有太多管理界面和其他組件的調(diào)用,以響應(yīng)生命周期的當(dāng)前狀態(tài)。管理多個(gè)組件會(huì)在生命周期方法(如 onStart() 和 onStop())中放置大量的代碼,這使得它們難以維護(hù)。
此外,無(wú)法保證組件會(huì)在 Activity 或 Fragment 停止之前啟動(dòng)myLocationListener。在我們需要執(zhí)行長(zhǎng)時(shí)間運(yùn)行的操作(如 onStart() 中的某種配置檢查)時(shí)尤其如此。在這種情況下,myLocationListener的onStop() 方法會(huì)在 onStart() 之前調(diào)用,這使得組件留存的時(shí)間比所需的時(shí)間要長(zhǎng),從而導(dǎo)致內(nèi)次泄漏。如下:
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, location -> {
// 更新 UI
});
}
@Override
public void onStart() {
super.onStart();
Util.checkUserStatus(result -> {
//如果checkUserStatus耗時(shí)較長(zhǎng),在activity停止后才回調(diào),那么myLocationListener啟動(dòng)后就沒(méi)辦法走stop()方法了,
//又因?yàn)閙yLocationListener持有activity,所以會(huì)造成內(nèi)存泄漏。
if (result) {
myLocationListener.start();
}
});
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
即2個(gè)問(wèn)題點(diǎn):
- activity的生命周期內(nèi)有大量管理組件的代碼,難以維護(hù)。
- 無(wú)法保證組件會(huì)在 Activity/Fragment停止后不執(zhí)行啟動(dòng)
Lifecycle庫(kù) 則可以 以彈性和隔離的方式解決這些問(wèn)題。
2.2 Lifecycle的使用
Lifecycle是一個(gè)庫(kù),也包含Lifecycle這樣一個(gè)類(lèi),Lifecycle類(lèi) 用于存儲(chǔ)有關(guān)組件(如 Activity 或 Fragment)的生命周期狀態(tài)的信息,并允許其他對(duì)象觀察此狀態(tài)。
2.2.1 引入依賴(lài)
1、非androidX項(xiàng)目 引入:
implementation "android.arch.lifecycle:extensions:1.1.1"
添加這一句代碼就依賴(lài)了如下的庫(kù):
2、androidX項(xiàng)目 引入:
如果項(xiàng)目已經(jīng)依賴(lài)了AndroidX:
implementation 'androidx.appcompat:appcompat:1.2.0'
那么我們就可以使用Lifecycle庫(kù)了,因?yàn)閍ppcompat依賴(lài)了androidx.fragment,而androidx.fragment下依賴(lài)了ViewModel和 LiveData,LiveData內(nèi)部又依賴(lài)了Lifecycle。
如果想要單獨(dú)引入依賴(lài),則如下:
在項(xiàng)目根目錄的build.gradle添加 google() 代碼庫(kù),然后app的build.gradle引入依賴(lài),官方給出的依賴(lài)如下:
//根目錄的 build.gradle
repositories {
google()
...
}
//app的build.gradle
dependencies {
def lifecycle_version = "2.2.0"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// 只有Lifecycles (不帶 ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// lifecycle注解處理器
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// 替換 - 如果使用Java8,就用這個(gè)替換上面的lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
//以下按需引入
// 可選 - 幫助實(shí)現(xiàn)Service的LifecycleOwner
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// 可選 - ProcessLifecycleOwner給整個(gè) app進(jìn)程 提供一個(gè)lifecycle
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// 可選 - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// 可選 - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}
看著有很多,實(shí)際上如果只使用Lifecycle,只需要引入lifecycle-runtime即可。但通常都是和 ViewModel、 LiveData 配套使用的,所以lifecycle-viewmodel、lifecycle-livedata 一般也會(huì)引入。
另外,lifecycle-process是給整個(gè)app進(jìn)程提供一個(gè)lifecycle,會(huì)面也會(huì)提到。
2.2.2 使用方法
Lifecycle的使用很簡(jiǎn)單:
- 1、生命周期擁有者 使用getLifecycle()獲取Lifecycle實(shí)例,然后代用addObserve()添加觀察者;
- 2、觀察者實(shí)現(xiàn)LifecycleObserver,方法上使用OnLifecycleEvent注解關(guān)注對(duì)應(yīng)生命周期,生命周期觸發(fā)時(shí)就會(huì)執(zhí)行對(duì)應(yīng)方法;
2.2.2.1 基本使用
在Activity(或Fragment)中 一般用法如下:
public class LifecycleTestActivity extends AppCompatActivity {
private String TAG = "Lifecycle_Test";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lifecycle_test);
//Lifecycle 生命周期
getLifecycle().addObserver(new MyObserver());
Log.i(TAG, "onCreate: ");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume: ");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause: ");
}
}
Activity(或Fragment)是生命周期的擁有者,通過(guò)getLifecycle()方法獲取到生命周期Lifecycle對(duì)象,Lifecycle對(duì)象使用addObserver方法 給自己添加觀察者,即MyObserver對(duì)象。當(dāng)Lifecycle的生命周期發(fā)生變化時(shí),MyObserver就可以感知到。
MyObserver是如何使用生命周期的呢?看下MyObserver的實(shí)現(xiàn):
public class MyObserver implements LifecycleObserver {
private String TAG = "Lifecycle_Test";
@OnLifecycleEvent(value = Lifecycle.Event.ON_RESUME)
public void connect(){
Log.i(TAG, "connect: ");
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_PAUSE)
public void disConnect(){
Log.i(TAG, "disConnect: ");
}
}
首先MyObserver實(shí)現(xiàn)了接口LifecycleObserver,LifecycleObserver用于標(biāo)記一個(gè)類(lèi)是生命周期觀察者。
然后在connectListener()、disconnectListener()上 分別都加了@OnLifecycleEvent注解,且value分別是Lifecycle.Event.ON_RESUME、Lifecycle.Event.ON_PAUSE,這個(gè)效果就是:connectListener()會(huì)在ON_RESUME時(shí)執(zhí)行,disconnectListener()會(huì)在ON_PAUSE時(shí)執(zhí)行。
我們打開(kāi)LifecycleTestActivity 然后退出,日志打印如下:
2020-11-09 17:25:40.601 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onCreate:
2020-11-09 17:25:40.605 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onResume:
2020-11-09 17:25:40.605 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: connect:
2020-11-09 17:25:51.841 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: disConnect:
2020-11-09 17:25:51.841 4822-4822/com.hfy.androidlearning I/Lifecycle_Test: onPause:
可見(jiàn)MyObserver的方法 確實(shí)是在對(duì)應(yīng)關(guān)注的生命周期觸發(fā)時(shí)調(diào)用。 當(dāng)然注解中的value你也寫(xiě)成其它 你關(guān)注的任何一個(gè)生命周期,例如Lifecycle.Event.ON_DESTROY。
2.2.2.2 MVP架構(gòu)中的使用
如果是 在MVP架構(gòu)中,那么就可以把presenter作為觀察者:
public class LifecycleTestActivity extends AppCompatActivity implements IView {
private String TAG = "Lifecycle_Test";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lifecycle_test);
//Lifecycle 生命周期
// getLifecycle().addObserver(new MyObserver());
//MVP中使用Lifecycle
getLifecycle().addObserver(new MyPresenter(this));
Log.i(TAG, "onCreate: ");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume: ");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause: ");
}
@Override
public void showView() {}
@Override
public void hideView() {}
}
//Presenter
class MyPresenter implements LifecycleObserver {
private static final String TAG = "Lifecycle_Test";
private final IView mView;
public MyPresenter(IView view) {mView = view;}
@OnLifecycleEvent(value = Lifecycle.Event.ON_START)
private void getDataOnStart(LifecycleOwner owner){
Log.i(TAG, "getDataOnStart: ");
Util.checkUserStatus(result -> {
//checkUserStatus是耗時(shí)操作,回調(diào)后檢查當(dāng)前生命周期狀態(tài)
if (owner.getLifecycle().getCurrentState().isAtLeast(STARTED)) {
start();
mView.showView();
}
});
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
private void hideDataOnStop(){
Log.i(TAG, "hideDataOnStop: ");
stop();
mView.hideView();
}
}
//IView
interface IView {
void showView();
void hideView();
}
這里是讓Presenter實(shí)現(xiàn)LifecycleObserver接口,同樣在方法上注解要觸發(fā)的生命周期,最后在Activity中作為觀察者添加到Lifecycle中。
這樣做好處是啥呢? 當(dāng)Activity生命周期發(fā)生變化時(shí),MyPresenter就可以感知并執(zhí)行方法,不需要在MainActivity的多個(gè)生命周期方法中調(diào)用MyPresenter的方法了。
- 所有方法調(diào)用操作都由組件本身管理:Presenter類(lèi)自動(dòng)感知生命周期,如果需要在其他的Activity/Fragment也使用這個(gè)Presenter,只需添加其為觀察者即可。
- 讓各個(gè)組件存儲(chǔ)自己的邏輯,減輕Activity/Fragment中代碼,更易于管理;
—— 上面提到的第一個(gè)問(wèn)題點(diǎn)就解決了。
另外,注意到 getDataOnStart()中耗時(shí)校驗(yàn)回調(diào)后,對(duì)當(dāng)前生命周期狀態(tài)進(jìn)行了檢查:至少處于STARTED狀態(tài)才會(huì)繼續(xù)執(zhí)行start()方法,也就是保證了Activity停止后不會(huì)走start()方法;
—— 上面提到的第二個(gè)問(wèn)題點(diǎn)也解決了。
2.2.3 自定義LifecycleOwner
在Activity中調(diào)用getLifecycle()能獲取到Lifecycle實(shí)例,那getLifecycle()是哪里定義的方法呢
?是接口LifecycleOwner,顧明來(lái)思義,生命周期擁有者:
/**
* 生命周期擁有者
* 生命周期事件可被 自定義的組件 用來(lái) 處理生命周期事件的變化,同時(shí)不會(huì)在Activity/Fragmen中寫(xiě)任何代碼
*/
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
Support Library 26.1.0及以上、AndroidX的 Fragment 和 Activity 已實(shí)現(xiàn) LifecycleOwner 接口,所以我們?cè)贏ctivity中可以直接使用getLifecycle()。
如果有一個(gè)自定義類(lèi)并希望使其成為L(zhǎng)ifecycleOwner,可以使用LifecycleRegistry類(lèi),它是Lifecycle的實(shí)現(xiàn)類(lèi),但需要將事件轉(zhuǎn)發(fā)到該類(lèi):
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry lifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry = new LifecycleRegistry(this);
lifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void onStart() {
super.onStart();
lifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
}
MyActivity實(shí)現(xiàn)LifecycleOwner,getLifecycle()返回lifecycleRegistry實(shí)例。lifecycleRegistry實(shí)例則是在onCreate創(chuàng)建,并且在各個(gè)生命周期內(nèi)調(diào)用markState()方法完成生命周期事件的傳遞。這就完成了LifecycleOwner的自定義,也即MyActivity變成了LifecycleOwner,然后就可以和 實(shí)現(xiàn)了LifecycleObserver的組件配合使用了。
補(bǔ)充一點(diǎn),觀察者的方法可以接受一個(gè)參數(shù)LifecycleOwner,就可以用來(lái)獲取當(dāng)前狀態(tài)、或者繼續(xù)添加觀察者。 若注解的是ON_ANY還可以接收Event,用于區(qū)分是哪個(gè)事件。如下:
class TestObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreated(LifecycleOwner owner) {
// owner.getLifecycle().addObserver(anotherObserver);
// owner.getLifecycle().getCurrentState();
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onAny(LifecycleOwner owner, Lifecycle.Event event) {
// event.name()
}
}
2.3 Application生命周期 ProcessLifecycleOwner
之前對(duì)App進(jìn)入前后臺(tái)的判斷是通過(guò)registerActivityLifecycleCallbacks(callback)方法,然后在callback中利用一個(gè)全局變量做計(jì)數(shù),在onActivityStarted()中計(jì)數(shù)加1,在onActivityStopped方法中計(jì)數(shù)減1,從而判斷前后臺(tái)切換。
而使用ProcessLifecycleOwner可以直接獲取應(yīng)用前后臺(tái)切換狀態(tài)。(記得先引入lifecycle-process依賴(lài))
使用方式和Activity中類(lèi)似,只不過(guò)要使用ProcessLifecycleOwner.get()獲取ProcessLifecycleOwner,代碼如下:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//注冊(cè)App生命周期觀察者
ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationLifecycleObserver());
}
/**
* Application生命周期觀察,提供整個(gè)應(yīng)用進(jìn)程的生命周期
*
* Lifecycle.Event.ON_CREATE只會(huì)分發(fā)一次,Lifecycle.Event.ON_DESTROY不會(huì)被分發(fā)。
*
* 第一個(gè)Activity進(jìn)入時(shí),ProcessLifecycleOwner將分派Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME。
* 而Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP,將在最后一個(gè)Activit退出后后延遲分發(fā)。如果由于配置更改而銷(xiāo)毀并重新創(chuàng)建活動(dòng),則此延遲足以保證ProcessLifecycleOwner不會(huì)發(fā)送任何事件。
*
* 作用:監(jiān)聽(tīng)?wèi)?yīng)用程序進(jìn)入前臺(tái)或后臺(tái)
*/
private static class ApplicationLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForeground() {
Log.w(TAG, "ApplicationObserver: app moved to foreground");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackground() {
Log.w(TAG, "ApplicationObserver: app moved to background");
}
}
}
看到確實(shí)很簡(jiǎn)單,和前面Activity的Lifecycle用法幾乎一樣,而我們使用ProcessLifecycleOwner就顯得很優(yōu)雅了。 生命周期分發(fā)邏輯已在注釋里說(shuō)明。
三、 源碼分析
Lifecycle的使用很簡(jiǎn)單,接下來(lái)就是對(duì)Lifecycle原理和源碼的解析了。
我們可以先猜下原理:LifecycleOwner(如Activity)在生命周期狀態(tài)改變時(shí)(也就是生命周期方法執(zhí)行時(shí)),遍歷觀察者,獲取每個(gè)觀察者的方法上的注解,如果注解是@OnLifecycleEvent且value是和生命周期狀態(tài)一致,那么就執(zhí)行這個(gè)方法。 這個(gè)猜測(cè)合理吧?下面你來(lái)看看。
3.1 Lifecycle類(lèi)
先來(lái)瞅瞅Lifecycle:
public abstract class Lifecycle {
//添加觀察者
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
//移除觀察者
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
//獲取當(dāng)前狀態(tài)
public abstract State getCurrentState();
//生命周期事件,對(duì)應(yīng)Activity生命周期方法
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY //可以響應(yīng)任意一個(gè)事件
}
//生命周期狀態(tài). (Event是進(jìn)入這種狀態(tài)的事件)
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
//判斷至少是某一狀態(tài)
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
Lifecycle 使用兩種主要枚舉跟蹤其關(guān)聯(lián)組件的生命周期狀態(tài):
- Event,生命周期事件,這些事件對(duì)應(yīng)Activity/Fragment生命周期方法。
- State,生命周期狀態(tài),而Event是指進(jìn)入一種狀態(tài)的事件。
Event觸發(fā)的時(shí)機(jī):
- ON_CREATE、ON_START、ON_RESUME事件,是在LifecycleOwner對(duì)應(yīng)的方法執(zhí)行 之后 分發(fā)。
- ON_PAUSE、ON_STOP、ON_DESTROY事件,是在LifecycleOwner對(duì)應(yīng)的方法調(diào)用 之前 分發(fā)。
這保證了LifecycleOwner是在這個(gè)狀態(tài)內(nèi)。
官網(wǎng)有個(gè)圖很清晰:
3.2 Activity對(duì)LifecycleOwner的實(shí)現(xiàn)
前面提到Activity實(shí)現(xiàn)了LifecycleOwner,所以才能直接使用getLifecycle(),具體是在androidx.activity.ComponentActivity中:
//androidx.activity.ComponentActivity,這里忽略了一些其他代碼,我們只看Lifecycle相關(guān)
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{
...
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this); //使用ReportFragment分發(fā)生命周期事件
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
這里忽略了一些其他代碼,我們只看Lifecycle相關(guān)。
看到ComponentActivity實(shí)現(xiàn)了接口LifecycleOwner,并在getLifecycle()返回了LifecycleRegistry實(shí)例。前面提到LifecycleRegistry是Lifecycle具體實(shí)現(xiàn)。
然后在onSaveInstanceState()中設(shè)置mLifecycleRegistry的狀態(tài)為State.CREATED,然后怎么沒(méi)有了?其他生命周期方法內(nèi)咋沒(méi)處理?what?和猜測(cè)的不一樣啊。 別急,在onCreate()中有這么一行:ReportFragment.injectIfNeededIn(this);,這個(gè)就是關(guān)鍵所在。
3.3 生命周期事件分發(fā)——ReportFragment
//專(zhuān)門(mén)用于分發(fā)生命周期事件的Fragment
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
//在API 29及以上,可以直接注冊(cè)回調(diào) 獲取生命周期
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks());
}
//API29以前,使用fragment 獲取生命周期
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
@SuppressWarnings("deprecation")
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
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的handleLifecycleEvent方法處理事件
}
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
...省略onStop、onDestroy
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
dispatch(getActivity(), event);
}
}
//在API 29及以上,使用的生命周期回調(diào)
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
...
@Override
public void onActivityPostCreated(@NonNull Activity activity,@Nullable Bundle savedInstanceState) {
dispatch(activity, Lifecycle.Event.ON_CREATE);
}
@Override
public void onActivityPostStarted(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_START);
}
@Override
public void onActivityPostResumed(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_RESUME);
}
@Override
public void onActivityPrePaused(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_PAUSE);
}
...省略onStop、onDestroy
}
}
首先injectIfNeededIn()內(nèi)進(jìn)行了版本區(qū)分:在API 29及以上 直接使用activity的registerActivityLifecycleCallbacks 直接注冊(cè)了生命周期回調(diào),然后給當(dāng)前activity添加了ReportFragment,注意這個(gè)fragment是沒(méi)有布局的。
然后, 無(wú)論LifecycleCallbacks、還是fragment的生命周期方法 最后都走到了 dispatch(Activity activity, Lifecycle.Event event)方法,其內(nèi)部使用LifecycleRegistry的handleLifecycleEvent方法處理事件。
而ReportFragment的作用就是獲取生命周期而已,因?yàn)閒ragment生命周期是依附Activity的。好處就是把這部分邏輯抽離出來(lái),實(shí)現(xiàn)activity的無(wú)侵入。如果你對(duì)圖片加載庫(kù)Glide比較熟,就會(huì)知道它也是使用透明Fragment獲取生命周期的。
3.4 生命周期事件處理——LifecycleRegistry
到這里,生命中周期事件的處理有轉(zhuǎn)移到了 LifecycleRegistry 中:
//LifecycleRegistry.java
//系統(tǒng)自定義的保存Observer的map,可在遍歷中增刪
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);//獲取event發(fā)生之后的將要處于的狀態(tài)
moveToState(next);//移動(dòng)到這個(gè)狀態(tài)
}
private void moveToState(State next) {
if (mState == next) {
return;//如果和當(dāng)前狀態(tài)一致,不處理
}
mState = next; //賦值新?tīng)顟B(tài)
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
return;
}
mHandlingEvent = true;
sync(); //把生命周期狀態(tài)同步給所有觀察者
mHandlingEvent = false;
}
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()) { //isSynced()意思是 所有觀察者都同步完了
mNewEventOccurred = false;
//mObserverMap就是 在activity中添加observer后 用于存放observer的map
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
...
static State getStateAfter(Event event) {
switch (event) {
case ON_CREATE:
case ON_STOP:
return CREATED;
case ON_START:
case ON_PAUSE:
return STARTED;
case ON_RESUME:
return RESUMED;
case ON_DESTROY:
return DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException("Unexpected event value " + event);
}
邏輯很清晰:使用getStateAfter()獲取event發(fā)生之后的將要處于的狀態(tài)(看前面那張圖很好理解),moveToState()是移動(dòng)到新?tīng)顟B(tài),最后使用sync()把生命周期狀態(tài)同步給所有觀察者。
注意到sync()中有個(gè)while循環(huán),很顯然是在遍歷觀察者。并且很顯然觀察者是存放在mObserverMap中的,而mObserverMap對(duì)觀察者的添加 很顯然 就是 Activity中使用getLifecycle().addObserver()這里:
//LifecycleRegistry.java
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//帶狀態(tài)的觀察者,這個(gè)狀態(tài)的作用:新的事件觸發(fā)后 遍歷通知所有觀察者時(shí),判斷是否已經(jīng)通知這個(gè)觀察者了
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//observer作為key,ObserverWithState作為value,存到mObserverMap
if (previous != null) {
return;//已經(jīng)添加過(guò),不處理
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
return;//lifecycleOwner退出了,不處理
}
//下面代碼的邏輯:通過(guò)while循環(huán),把新的觀察者的狀態(tài) 連續(xù)地 同步到最新?tīng)顟B(tài)mState。
//意思就是:雖然可能添加的晚,但把之前的事件一個(gè)個(gè)分發(fā)給你(upEvent方法),即粘性
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);//計(jì)算目標(biāo)狀態(tài)
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
sync();
}
mAddingObserverCounter--;
}
用observer創(chuàng)建帶狀態(tài)的觀察者ObserverWithState,observer作為key、ObserverWithState作為value,存到mObserverMap。 接著做了安全判斷,最后把新的觀察者的狀態(tài) 連續(xù)地 同步到最新?tīng)顟B(tài)mState,意思就是:雖然可能添加的晚,但會(huì)把之前的事件一個(gè)個(gè)分發(fā)給你,即粘性。
回到剛剛sync()的while循環(huán),看看如何處理分發(fā)事件:
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
+ "new events from it.");
return;
}
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);
}
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;
}//最老的和最新的觀察者的狀態(tài)一致,都是ower的當(dāng)前狀態(tài),說(shuō)明已經(jīng)同步完了
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator = mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {//正向遍歷,從老到新
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));//observer獲取事件
popParentState();
}
}
}
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator = mObserverMap.descendingIterator();
while (descendingIterator.hasNext() && !mNewEventOccurred) {//反向遍歷,從新到老
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);//observer獲取事件
popParentState();
}
}
}
循環(huán)條件是!isSynced(),若最老的和最新的觀察者的狀態(tài)一致,且都是ower的當(dāng)前狀態(tài),說(shuō)明已經(jīng)同步完了。
沒(méi)有同步完就進(jìn)入循環(huán)體:
- mState比最老觀察者狀態(tài)小,走backwardPass(lifecycleOwner):從新到老分發(fā),循環(huán)使用downEvent()和observer.dispatchEvent(),連續(xù)分發(fā)事件;
- mState比最新觀察者狀態(tài)大,走forwardPass(lifecycleOwner):從老到新分發(fā),循環(huán)使用upEvent()和observer.dispatchEvent(),連續(xù)分發(fā)事件。
接著ObserverWithState類(lèi)型的observer就獲取到了事件,即observer.dispatchEvent(lifecycleOwner, event),下面來(lái)看看它是如何讓加了對(duì)應(yīng)注解的方法執(zhí)行的。
3.5 事件回調(diào)后 方法執(zhí)行
我們繼續(xù)看下 ObserverWithState:
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;
}
}
mState的作用是:新的事件觸發(fā)后 遍歷通知所有觀察者時(shí),判斷是否已經(jīng)通知這個(gè)觀察者了,即防止重復(fù)通知。
mLifecycleObserver是使用Lifecycling.getCallback(observer)獲取的GenericLifecycleObserver實(shí)例。GenericLifecycleObserver是接口,繼承自L(fǎng)ifecycleObserver:
//接受生命周期改變并分發(fā)給真正的觀察者
public interface LifecycleEventObserver extends LifecycleObserver {
//生命周期狀態(tài)變化
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
也就說(shuō),LifecycleEventObserver 給 LifecycleObserver 增加了感知生命周期狀態(tài)變化的能力。
看看Lifecycling.getCallback(observer):
@NonNull
static LifecycleEventObserver lifecycleEventObserver(Object object) {
...省略很多類(lèi)型判斷的代碼
return new ReflectiveGenericLifecycleObserver(object);
}
方法內(nèi)有很多對(duì)observer進(jìn)行類(lèi)型判斷的代碼,我們這里關(guān)注的是ComponentActivity,所以L(fǎng)ifecycleEventObserver的實(shí)現(xiàn)類(lèi)就是ReflectiveGenericLifecycleObserver了:
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());//存放了event與加了注解方法的信息
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);//執(zhí)行對(duì)應(yīng)event的觀察者的方法
}
}
它的onStateChanged()方法內(nèi)部使用CallbackInfo的invokeCallbacks方法,這里應(yīng)該就是執(zhí)行觀察者的方法了。
ClassesInfoCache內(nèi)部用Map存了 所有觀察者的回調(diào)信息,CallbackInfo是當(dāng)前觀察者的回調(diào)信息。
先看下CallbackInfo實(shí)例的創(chuàng)建,ClassesInfoCache.sInstance.getInfo(mWrapped.getClass()):
//ClassesInfoCache.java
private final Map<Class, CallbackInfo> mCallbackMap = new HashMap<>();//所有觀察者的回調(diào)信息
private final Map<Class, Boolean> mHasLifecycleMethods = new HashMap<>();//觀察者是否有注解了生命周期的方法
CallbackInfo getInfo(Class<?> klass) {
CallbackInfo existing = mCallbackMap.get(klass);//如果已經(jīng)存在當(dāng)前觀察者回調(diào)信息 直接取
if (existing != null) {
return existing;
}
existing = createInfo(klass, null);//沒(méi)有就去收集信息并創(chuàng)建
return existing;
}
private CallbackInfo createInfo(Class<?> klass, @Nullable Method[] declaredMethods) {
Class<?> superclass = klass.getSuperclass();
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();//生命周期事件到來(lái) 對(duì)應(yīng)的方法
...
Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);//反射獲取觀察者的方法
boolean hasLifecycleMethods = false;
for (Method method : methods) {//遍歷方法 找到注解OnLifecycleEvent
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation == null) {
continue; //沒(méi)有注解OnLifecycleEvent 就return
}
hasLifecycleMethods = true;//有注解OnLifecycleEvent
Class<?>[] params = method.getParameterTypes(); //獲取方法參數(shù)
int callType = CALL_TYPE_NO_ARG;
if (params.length > 0) { //有參數(shù)
callType = CALL_TYPE_PROVIDER;
if (!params[0].isAssignableFrom(LifecycleOwner.class)) {
throw new IllegalArgumentException(//第一個(gè)參數(shù)必須是LifecycleOwner
"invalid parameter type. Must be one and instanceof LifecycleOwner");
}
}
Lifecycle.Event event = annotation.value();
if (params.length > 1) {
callType = CALL_TYPE_PROVIDER_WITH_EVENT;
if (!params[1].isAssignableFrom(Lifecycle.Event.class)) {
throw new IllegalArgumentException(//第二個(gè)參數(shù)必須是Event
"invalid parameter type. second arg must be an event");
}
if (event != Lifecycle.Event.ON_ANY) {
throw new IllegalArgumentException(//有兩個(gè)參數(shù) 注解值只能是ON_ANY
"Second arg is supported only for ON_ANY value");
}
}
if (params.length > 2) { //參數(shù)不能超過(guò)兩個(gè)
throw new IllegalArgumentException("cannot have more than 2 params");
}
MethodReference methodReference = new MethodReference(callType, method);
verifyAndPutHandler(handlerToEvent, methodReference, event, klass);//校驗(yàn)方法并加入到map handlerToEvent 中
}
CallbackInfo info = new CallbackInfo(handlerToEvent);//獲取的 所有注解生命周期的方法handlerToEvent,構(gòu)造回調(diào)信息實(shí)例
mCallbackMap.put(klass, info);//把當(dāng)前觀察者的回調(diào)信息存到ClassesInfoCache中
mHasLifecycleMethods.put(klass, hasLifecycleMethods);//記錄 觀察者是否有注解了生命周期的方法
return info;
}
- 如果不存在當(dāng)前觀察者回調(diào)信息,就使用createInfo()方法收集創(chuàng)建
- 先反射獲取觀察者的方法,遍歷方法 找到注解了OnLifecycleEvent的方法,先對(duì)方法的參數(shù)進(jìn)行了校驗(yàn)。
- 第一個(gè)參數(shù)必須是LifecycleOwner;第二個(gè)參數(shù)必須是Event;有兩個(gè)參數(shù) 注解值只能是ON_ANY;參數(shù)不能超過(guò)兩個(gè)
- 校驗(yàn)方法并加入到map,key是方法,value是Event。map handlerToEvent是所有的注解了生命周期的方法。
- 遍歷完,然后用 handlerToEvent來(lái)構(gòu)造 當(dāng)前觀察者回調(diào)信息CallbackInfo,存到ClassesInfoCache的mCallbackMap中,并記錄 觀察者是否有注解了生命周期的方法。
整體思路還是很清晰的,繼續(xù)看CallbackInfo的invokeCallbacks方法:
static class CallbackInfo {
final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers;//Event對(duì)應(yīng)的多個(gè)方法
final Map<MethodReference, Lifecycle.Event> mHandlerToEvent;//要回調(diào)的方法
CallbackInfo(Map<MethodReference, Lifecycle.Event> handlerToEvent) {
mHandlerToEvent = handlerToEvent;
mEventToHandlers = new HashMap<>();
//這里遍歷mHandlerToEvent來(lái)獲取mEventToHandlers
for (Map.Entry<MethodReference, Lifecycle.Event> entry : handlerToEvent.entrySet()) {
Lifecycle.Event event = entry.getValue();
List<MethodReference> methodReferences = mEventToHandlers.get(event);
if (methodReferences == null) {
methodReferences = new ArrayList<>();
mEventToHandlers.put(event, methodReferences);
}
methodReferences.add(entry.getKey());
}
}
@SuppressWarnings("ConstantConditions")
void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);//執(zhí)行對(duì)應(yīng)event的方法
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,target);//執(zhí)行注解了ON_ANY的方法
}
private static void invokeMethodsForEvent(List<MethodReference> handlers,
LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
if (handlers != null) {
for (int i = handlers.size() - 1; i >= 0; i--) {//執(zhí)行Event對(duì)應(yīng)的多個(gè)方法
handlers.get(i).invokeCallback(source, event, mWrapped);
}
}
}
}
很好理解,執(zhí)行對(duì)應(yīng)event的方法、執(zhí)行注解了ON_ANY的方法。其中mEventToHandlers是在創(chuàng)建CallbackInfo時(shí)由遍歷mHandlerToEvent來(lái)獲取,存放了每個(gè)Event對(duì)應(yīng)的多個(gè)方法。
最后看看handlers.get(i).invokeCallback,即MethodReference中:
static class MethodReference {
...
void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
try {
switch (mCallType) {
case CALL_TYPE_NO_ARG:
mMethod.invoke(target);//沒(méi)有參數(shù)的
break;
case CALL_TYPE_PROVIDER:
mMethod.invoke(target, source);//一個(gè)參數(shù)的:LifecycleOwner
break;
case CALL_TYPE_PROVIDER_WITH_EVENT:
mMethod.invoke(target, source, event);//兩個(gè)參數(shù)的:LifecycleOwner,Event
break;
}
}
...
}
...
}
根據(jù)不同參數(shù)類(lèi)型,執(zhí)行對(duì)應(yīng)方法。
到這里,整個(gè)流程就完整了。實(shí)際看了這么一大圈,基本思路和我們的猜想是一致的。
這里借Android Jetpack架構(gòu)組件(三)一文帶你了解Lifecycle(原理篇)的圖總結(jié)下:
四、總結(jié)
本文先介紹了Jetpack和AAC的概念,這是Android官方推薦的通用開(kāi)發(fā)工具集。其中AAC是架構(gòu)組件,是本系列文章的介紹內(nèi)容。接著介紹了AAC的基礎(chǔ)組件Lifecycle,它能讓開(kāi)發(fā)者更好的管理Activity/Fragment生命周期。最后詳細(xì)分析了Lifecycle源碼及原理。
Jetpack的AAC是我們后續(xù)開(kāi)發(fā)Android必備知識(shí),也是完成MVVM架構(gòu)的基礎(chǔ)。Lifecycle更是AAC中的基礎(chǔ),所以完整掌握本篇內(nèi)容十分必要。
.
感謝與參考:
Android Jetpack架構(gòu)組件(三)一文帶你了解Lifecycle(原理篇)
Android架構(gòu)組件(2)LifecycleRegistry 源碼分析
.
你的 點(diǎn)贊、評(píng)論,是對(duì)我的巨大鼓勵(lì)!