我一直在使用Mvvmcross来开发Android应用程序。我正在处理旋转期间ViewModel生命周期的问题。看起来通常在旋转期间保留ViewModel。但是,当我在MvxTabActivity中呈现ViewModels时,情况并非如此。当旋转发生时,它总是调用ViewModel构造函数。
我使用了与N + 1教程https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-25-Tabbed中类似的代码结构。
有没有办法修改本教程,以便在使用MvxTabActivity时在旋转期间将ViewModel保留在内存中?
答案 0 :(得分:4)
尝试解决Android轮换行为的默认ViewModel缓存基于IMvxSingleViewModelCache
- 所以它无法应对多个活动和多个ViewModel并不太令人惊讶。
有关声明和使用此接口的位置,请参阅https://github.com/slodge/MvvmCross/search?q=IMvxSingleViewModelCache&ref=cmdform
如果这种行为让您感到不安,那么您应该可以通过以下方式解决这个问题:
Android处理Fragment生命周期与Activity的生命周期不同。
IMvxSingleViewModelCache
例如,通过“子”命名约定来识别您的子视图模型应该很简单。
完成此操作后,您可以执行以下操作:
public class MyCustomViewModelCache
: IMvxSingleViewModelCache
{
private const string BundleCacheKey = "__mvxVMCacheKey";
private int _counter;
private IMvxViewModel _currentViewModel;
public void Cache(IMvxViewModel toCache, Bundle bundle)
{
if (toCache != null
&& toCache.GetType().Name.StartsWith("Child"))
{
// don't worry about caching child view models
return;
}
_currentViewModel = toCache;
_counter++;
if (_currentViewModel == null)
{
return;
}
bundle.PutInt(BundleCacheKey, _counter);
}
public IMvxViewModel GetAndClear(Bundle bundle)
{
var storedViewModel = _currentViewModel;
_currentViewModel = null;
if (bundle == null)
return null;
var key = bundle.GetInt(BundleCacheKey);
var toReturn = (key == _counter) ? storedViewModel : null;
return toReturn;
}
}
此课程基于MvxSingleViewModelCache.cs,只有一小部分内容。
您可以在安装程序的IMvxSingleViewModelCache
期间将此类的实例注册为InitializeLastChance
单例。
Mvx.RegisterSingleton<IMvxSingleViewModelCache>(new MyCustomViewModelCache());
完成此操作后,主页/选项卡活动应该(我认为)继续工作 - 并且它会在轮换后将视图模型传递给选项卡子项。
(IMvxSingleViewModelCache
的其他可能性是可能的 - 例如它可以缓存多个视图模型 - 但请不要让它过多地缓存太多的视图模型,否则你可能会遇到“内存不足”的情况)
如果你添加android:configChanges="orientation"
标志(或它的monodroid等效属性),你可以自己处理旋转。