Поэтому я не уверен, как я к этому отношусь, но я нашел решение своей проблемы. Я обнаружил, что SuspensionHost в конечном итоге сам создает AppState. Затем он берет сохраненные данные и повторно гидратирует все, что вы хранили. Чтобы использовать это, мне пришлось сделать следующее
public App()
{
InitializeComponent();
try
{
RxApp.SuspensionHost.CreateNewAppState = () =>
{
return new AppBootstrapper();
};
RxApp.SuspensionHost.SetupDefaultSuspendResume(new AkavacheSuspensionDriver<AppBootstrapper>());
RxApp.SuspensionHost.ObserveAppState<AppBootstrapper>().Subscribe<AppBootstrapper>((a) =>
{
Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
{
var bootstrapper = a;
MainPage = bootstrapper.CreateMainPage();
});
});
AppCenterLog.Info("Start", "Application Started");
}
catch (Exception ex)
{
//Crash reporting not available in appcenter - using event analytics as temp solution
Analytics.TrackEvent("Bootstrap Runtime Error", new Dictionary<string, string> {
{ "Exception", ex.Message }
});
}
}
Таким образом, в конце приложение загрузится, отобразит пустой экран, а затем узел подвески создаст новый загрузчик приложений, заполнит сохраненные данные и обновит AppState. Используя это новое состояние приложения, я могу установить MainPage.
В AppBootLoader я сохраняю только следующее как Datamember
[DataMember]
public ICollection<NavStackPersistence> NavStack
{
get
{
ICollection<NavStackPersistence> navStack = new List<NavStackPersistence>();
foreach (var vm in Router.NavStackPersistence)
{
navStack.Add(new NavStackPersistence()
{
Path = vm.UrlPathSegment,
Name = vm.ToString(),
ViewModel = (LoginViewModel)vm
});
}
return navStack;
}
set
{
if (value != null)
{
foreach (var vm in value)
{
this.Router
.NavigateAndReset
.Execute(vm.ViewModel)
.Subscribe();
}
// TODO in here we set the router path??
}
}
}
И, наконец, класс, который я сохраняю
public class NavStackPersistence
{
public string Name { get; set; }
public string Path { get; set; }
public LoginViewModel ViewModel { get; set; }
}
Это успешно загрузит AppBootloader, заполнит NavStack коллекцией, и каждый элемент в этой коллекции (сейчас только loginViewModel) также будет инициализирован и повторно гидратирован. В моем примере здесь указано имя и полностью заполненная модель LoginViewModel, которая при переходе к ней по-прежнему сохраняет использованные имя пользователя и пароль.
У кого-нибудь из команды ReactiveUI есть какие-либо комментарии о том, как это реализовано? Есть ли лучший способ подойти к этому?
КСТАТИ. Любой, кто хочет использовать это для UWP в xamarin, должен был добавить это в файл класса UWP App.CS.
private AutoSuspendHelper autoSuspendHelper;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
autoSuspendHelper = new AutoSuspendHelper(this);
this.InitializeComponent();
this.Suspending += OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
autoSuspendHelper.OnLaunched(args);
....
}
person
Joe Harvey
schedule
14.12.2018