眾所周知,ViewModel的作用在于以可感知生命周期的方式存儲與管理UI相關的數(shù)據(jù),它允許數(shù)據(jù)在例如屏幕旋轉這樣的配置發(fā)生變化時得以保存,那系統(tǒng)又是如何做到保存ViewModel的呢,讓我們從源碼中去溯本追源吧。
AndroidX支持庫中的AppCompatActivity繼承自FragmentActivity,而后者又繼承自ComponentActivity,ComponentAcitivty實現(xiàn)了ViewModelStoreOwner接口,該接口定義如下:
很顯然,實現(xiàn)該接口的類需要能夠提供一個ViewModelStore,而ViewModelStore即為用于存儲ViewModel對象的倉庫,其內(nèi)部通過一個HashMap管理ViewModel。
當需要獲取ViewModel時,需先創(chuàng)建ViewModelProvider實例,在2.2.0版本的ViewModel庫中,不再通過ViewModelProvider的靜態(tài)of方法獲取實例,而需要通過ViewModelProvider的構造函數(shù)去創(chuàng)建實例,其存在如下構造函數(shù):



那么這個NonConfigurationInstances又是從何而來的呢,通過方法跟蹤,可找到其在Activity的attach方法中通過方法參數(shù)傳入
@UnsupportedAppUsage
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
……
mLastNonConfigurationInstances = lastNonConfigurationInstances;
……
}
Activity的attach方法是在Activity的加載流程中由ActivityThread的performLaunchActivity調(diào)用的,調(diào)用時傳入的是ActivityRecordClient中的NonConfigurationInstances對象,那ActivityRecordClient又是在什么時候保存的NonConfigurationInstances對象的呢,這就要從Activity因為配置變化被銷毀時查起了。
當Activity因為配置變化被銷毀時,在其銷毀流程中ActivityThread會調(diào)用performDestroyActivity方法,該方法內(nèi)部會回調(diào)Activity的retainNonConfigurationInstances方法獲取NonConfigurationInstances并保存在ActivityRecordClient中以備之后Activity重建之需,以下是retainNonConfigurationInstances方法的部分流程:
NonConfigurationInstances retainNonConfigurationInstances() {
Object activity = onRetainNonConfigurationInstance();
……
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.activity = activity;
……
return nci;
}
其中onRetainNonConfigurationInstance()方法由ComponentActivity進行了覆寫:
onRetainNonConfigurationInstances方法的主要邏輯就是創(chuàng)建了一個NonConfigurationInstances對象(此NonConfigurationInstances類與前頭的NonConfigurationInstances類不是同一個類),并將當前Activity的ViewModelStore保存到了所創(chuàng)建的對象的viewModelStore變量中,從而使得Activity在銷毀后重建時能獲取到銷毀前的ViewModelStore,進而可獲取到銷毀前的ViewModel。onRetainNoConfigurationInstance方法返回的NonConfigurationInstance對象最終被存儲到了retainNonConfigurationInstances方法中創(chuàng)建的NonConfigurationInstances對象的activity變量里。
