gpt4 book ai didi

android - ViewModel 如何在配置更改中幸存

转载 作者:行者123 更新时间:2023-12-02 15:30:02 24 4
gpt4 key购买 nike

我正在尝试在我的应用程序中使用 ViewModel。我想到的问题是 View 模型如何在配置更改中幸存下来。我读了很多博客文章说“

It will create a HolderFragment to add to your activity or your fragment, it's invisible, when the configuration changed, activity destroyed, but holder fragment is still alive

这是有道理的。但我尝试对此进行更多探索,发现在支持库 27.1.0+ 中,他们已经删除了 HolderFragment,其描述为

Deprecate ViewModelStores.of() and the HolderFragment it relies on as they are no longer needed link for android.googlesource.

现在的问题是他们现在如何做同样的事情?

最佳答案

使用ViewModelProviders.of()方法创建的ViewModel存储在ViewModelStore hashmap中,因此真正的问题是ViewModelStore如何存储。

对于 Activity 来说,这个逻辑很简单。 ViewModelStore 使用 onRetainNonConfigurationInstance 方法存储:

@Override
@Nullable
public final Object onRetainNonConfigurationInstance() {
Object custom = onRetainCustomNonConfigurationInstance();

ViewModelStore viewModelStore = mViewModelStore;
if (viewModelStore == null) {
// No one called getViewModelStore(), so see if there was an existing
// ViewModelStore from our last NonConfigurationInstance
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
viewModelStore = nc.viewModelStore;
}
}

if (viewModelStore == null && custom == null) {
return null;
}

NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = viewModelStore;
return nci;
}

对于 fragment 来说,事情有点复杂。 FragmentManagerImpl 现在有一个名为 mNonConfig 的字段:

私有(private) FragmentManagerViewModel mNonConfig;

它存储 Fragment 的 UUID 的 HashMap 和 ViewModelStore

mNonConfig字段在FragmentManagerImpl#attachController方法中初始化:

    public void attachController(@NonNull FragmentHostCallback host,
@NonNull FragmentContainer container, @Nullable final Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
mHost = host;
mContainer = container;
mParent = parent;
if (mParent != null) {
// Since the callback depends on us being the primary navigation fragment,
// update our callback now that we have a parent so that we have the correct
// state by default
updateOnBackPressedCallbackEnabled();
}
// Set up the OnBackPressedCallback
if (host instanceof OnBackPressedDispatcherOwner) {
OnBackPressedDispatcherOwner dispatcherOwner = ((OnBackPressedDispatcherOwner) host);
mOnBackPressedDispatcher = dispatcherOwner.getOnBackPressedDispatcher();
LifecycleOwner owner = parent != null ? parent : dispatcherOwner;
mOnBackPressedDispatcher.addCallback(owner, mOnBackPressedCallback);
}

// Get the FragmentManagerViewModel
if (parent != null) {
mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
} else if (host instanceof ViewModelStoreOwner) {
ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
} else {
mNonConfig = new FragmentManagerViewModel(false);
}
}

关于android - ViewModel 如何在配置更改中幸存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58903637/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com