ComponentActivity 코드
@Suppress("deprecation")
final override fun onRetainNonConfigurationInstance(): Any? {
// Maintain backward compatibility.
val custom = onRetainCustomNonConfigurationInstance()
var viewModelStore = _viewModelStore
if (viewModelStore == null) {
// No one called getViewModelStore(), so see if there was an existing
// ViewModelStore from our last NonConfigurationInstance
val nc = lastNonConfigurationInstance as NonConfigurationInstances?
if (nc != null) {
viewModelStore = nc.viewModelStore
}
}
if (viewModelStore == null && custom == null) {
return null
}
// 'NonConfigurationInstances'라는 내부 전용 보관 상자 생성
val nci = NonConfigurationInstances()
nci.custom = custom
nci.viewModelStore = viewModelStore // 여기에 현재의 ViewModel들이 담긴 바구니를 넣음
return nci // 이 상자를 안드로이드 시스템(OS)에 맡김
}
onPause() -> onStop() -> [이 시점에 호출] -> onDestroy()
ActivityThread.java
void performDestroyActivity(ActivityClientRecord r, boolean finishing, boolean getNonConfigInstance, String reason) {
Class < ? extends Activity > activityClass;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
activityClass = r.activity.getClass();
if (finishing) {
r.activity.mFinished = true;
}
performPauseActivityIfNeeded(r, "destroy");
if (!r.stopped) {
callActivityOnStop(r, false /* saveState */, "destroy");
}
if (getNonConfigInstance) {
try {
r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException ("Unable to retain activity "
+ r.intent.getComponent().toShortString() + ": " + e.toString(), e);
}
}
}
...
}
이후 액티비티 재생성시 다음 코드로부터 ViewModelStore를 가져옴
ComponentActivity.kt
override val viewModelStore: ViewModelStore
/**
* Returns the [ViewModelStore] associated with this activity
*
* Overriding this method is no longer supported and this method will be made `final` in a
* future version of ComponentActivity.
*
* @return a [ViewModelStore]
* @throws IllegalStateException if called before the Activity is attached to the
* Application instance i.e., before onCreate()
*/
get() {
checkNotNull(application) {
("Your activity is not yet attached to the " +
"Application instance. You can't request ViewModel before onCreate call.")
}
ensureViewModelStore()
return _viewModelStore!!
}
private fun ensureViewModelStore() {
if (_viewModelStore == null) {
val nc = lastNonConfigurationInstance as NonConfigurationInstances?
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
_viewModelStore = nc.viewModelStore
}
if (_viewModelStore == null) {
_viewModelStore = ViewModelStore()
}
}
}
lastNonConfigurationInstance로 파괴되기 전에 저장한 기존의 ViewModelStore를 가지고 있는NonConfigurationInstances를 가져와서 값으로 설정한다.
정리는 완전히 죽을 때만 하고 이것은 ComponentActivity의 init에서 설정
init {
...
@Suppress("LeakingThis")
lifecycle.addObserver(
LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
// Clear out the available context
contextAwareHelper.clearAvailableContext()
// And clear the ViewModelStore
if (!isChangingConfigurations) {
viewModelStore.clear() <- 여기
}
reportFullyDrawnExecutor.activityDestroyed()
}
}
)
...
}