Жизненный цикл ViewModel MvvmCross во время вращения
Я использую Mvvmcross для разработки приложения для Android. Я имею дело с проблемой жизненного цикла ViewModel во время ротации. Кажется, что обычно ViewModel сохраняется во время вращения. Однако это не так, когда я представляю ViewModels в MvxTabActivity. Когда происходит вращение, он всегда вызывает конструктор ViewModel.
Я использовал аналогичную структуру кода, как в учебнике N+1 https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-25-Tabbed.
есть ли способ изменить этот учебник, чтобы сохранить ViewModels в памяти во время вращения при использовании MvxTabActivity?
1 ответов
кэширование ViewModel по умолчанию, которое пытается обойти поведение вращения Android, основано на IMvxSingleViewModelCache
- поэтому неудивительно, что он не может справиться с несколькими действиями и несколькими моделями просмотра.
для того, где этот интерфейс объявлен и используется, см. https://github.com/slodge/MvvmCross/search?q=IMvxSingleViewModelCache&ref=cmdform
если это поведение беспокоит вас, то вы должны быть в состоянии обойти его одним из :
1. Используйте вкладки на основе фрагментов, а не на основе активности
Android обрабатывает жизненный цикл фрагмента по-разному для активности.
2. Или продолжайте использовать вкладки на основе активности, но реализуйте свой собственный 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;
}
}
этого класса on MvxSingleViewModelCache.cs С одним небольшим добавлением.
вы можете зарегистрировать экземпляр этого класса как IMvxSingleViewModelCache
синглтон в InitializeLastChance
настройки вашей системы.
Mvx.RegisterSingleton<IMvxSingleViewModelCache>(new MyCustomViewModelCache());
после этого активность home / tab должна (я думаю) продолжать работать - и она передаст viewmodels вниз на вкладку children после вращения.
(другие возможности IMvxSingleViewModelCache
возможны-например, он может кэшировать несколько моделей просмотра - но, пожалуйста, не пусть он кэширует слишком много моделей просмотра слишком долго или вы можете столкнуться с условиями "из памяти")
3. Или выключите обработку вращения Android
если добавить android:configChanges="orientation"
флаг (или его эквивалент атрибута monodroid), то вы можете просто регулируют вращение себя.