When is the viewmodel onCleared called

旧巷老猫 提交于 2019-12-03 14:37:25

问题


Are ViewModels independent of activity/fragment lifecycles or just their configuration changes. When will they cease to exist and the subsequent onCleared() method called. Can the viewModel be shared with another Activity ?

A situation:

Activity1+viewModel1--->(rotation)--->Activity1+viewModel1
--->(launch Intent)--->Activity2+viewModel1

is this sharing possible and is it a good practice.

Also, since the app lifecycle callbacks, onPause->onStop->onDestroy is same for both

1.activity rotating and

2.when an Activity ends,

how is a ViewModel figuring out internally the right time to call onCleared and finally end its lifecycle.


Findings:

the ViewModel uses a holderFragment internally to hold an instance of the activity and uses the setRetainInstance method like fragments to account for configuration changes.

Source: dive-inside-of-androids-viewmodel-architecture-components


回答1:


Are ViewModels independent of activity/fragment lifecycles or just their configuration changes.

They are independent of configuration changes and are cleared when activity/fragment is destroyed.

Following is the lifecycle of ViewModel from official site:

Can the viewModel be shared with another Activity ?

You shouldn't do that with Activities. However fragments can share a ViewModel using their activity scope to handle communication between them




回答2:


check method onDestroy() in Fragment.java

public void onDestroy() {
        this.mCalled = true;
        FragmentActivity activity = this.getActivity();
        boolean isChangingConfigurations = activity != null && activity.isChangingConfigurations();
        if (this.mViewModelStore != null && !isChangingConfigurations) {
            this.mViewModelStore.clear();
        }

    }

The variant isChangingConfigurations is true when the Activity rotates, the viewModelStore method clear() is not called.

When Activity is destroyed, isChangingConfigurations is false, the viewModelStore will be cleared.




回答3:


okay,through the source code,we know the ViewModel bind with HolderFragment.you can from the code in class ViewModelProviders to find it.

@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity,
        @NonNull Factory factory) {
    checkApplication(activity);
    return new ViewModelProvider(ViewModelStores.of(activity), factory);
}

next,in class HolderFragment on it's OnDestroy() you can find

@Override
public void onDestroy() {
    super.onDestroy();
    mViewModelStore.clear();
}

Last,open it,

public final void clear() {
 for (ViewModel vm : mMap.values()) {
        vm.onCleared();
   }
    mMap.clear();
}

now ,maybe you have know it.just like the picture above.when the fragment finished,it cleared; when activity recreate,the fragment's onDestroy() will not be invoked,because

public HolderFragment() {
    setRetainInstance(true);
}

hope it can help you.




回答4:


If you follow the trail (Check super class) AppCompatActivity --> FragmentActivity --> ComponentActivity

ComponentActivity observe the lifecycle state.

onDestory() calls at configuration change (such as screen rotation) but viewModel doesn't get destroy because of the following condition.

getLifecycle().addObserver(new GenericLifecycleObserver() {
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    if (!isChangingConfigurations()) {
                        getViewModelStore().clear();
                    }
                }
            }
        });


来源:https://stackoverflow.com/questions/50983738/when-is-the-viewmodel-oncleared-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!