Android会在Activity执行销毁的生命周期之前,会将所有你想保存的数据放到NonConfigurationInstances对象里面, 然后会将Activity的NonConfigurationInstance对象放进ActivityClientRecord里面, 我们知道启动一个Activity会为他创建一个ActivityClientRecord对象,这个对象只会有一个,你现在是旋转屏幕,这个不涉及ActivityClientRecord对象的重新创建,所以你保存在里面的旧数据就会一直在.
1 2 3 4 5 6 7 8 9
| class ActivityThread{ void performDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges, boolean getNonConfigInstance, String reason){ r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
} }
|
现在看下Activity.retainNonConfigurationInstances()方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Activity{ NonConfigurationInstances retainNonConfigurationInstances() { Object activity = onRetainNonConfigurationInstance();
HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
NonConfigurationInstances nci = new NonConfigurationInstances(); nci.activity = activity; nci.children = children; nci.fragments = fragments;
return nci; } }
|
然后ComponentActivity重写了onRetainNonConfigurationInstance方法:
1 2 3 4 5 6 7 8 9 10 11 12
| class ComponentActivity{ public final Object onRetainNonConfigurationInstance() { Object custom = onRetainCustomNonConfigurationInstance();
ViewModelStore viewModelStore = mViewModelStore;
NonConfigurationInstances nci = new NonConfigurationInstances(); nci.custom = custom; nci.viewModelStore = viewModelStore; return nci; } }
|
可以看到在ComponentActivity重写了onRetainNonConfigurationInstance方法,将Activity的ViewModeStore放进了NonConfigurationInstance里面.
上面是关于viewModelStore存的操作,下面看下是怎么取的.
取的阶段发生在Activity的attach阶段:
1 2 3 4 5 6 7 8 9 10
| class ActivityThread{ private Activity performLaunchActivity(ActivityClientRecord r,Intent customInstent){ activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback, r.assistToken, r.shareableActivityToken)) } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Activity{ 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, IBinder shareableActivityToken){ mLastNonConfigurationInstances = lastNonConfigurationInstances; } }
|