MAUI Android应用后台销毁后恢复抛异常的解决咨询
解决Prism MAUI Android后台销毁后恢复异常的方案
核心原因
Android系统内存紧张时会销毁后台应用进程,而Prism框架的导航状态未被正确持久化,导致应用恢复时MainPage未完成初始化,触发「Either set MainPage or override CreateWindows」异常。
具体解决方法
1. 持久化并恢复Prism导航状态
- 在
App.xaml.cs中重写OnSleep,保存当前导航栈的URI路径:protected override void OnSleep() { base.OnSleep(); var navigationService = Container.Resolve<INavigationService>(); var navigationState = navigationService.GetNavigationUriPath(); Preferences.Set("LastNavigationState", navigationState); } - 重写
OnInitialize方法,启动时恢复导航状态:protected override async void OnInitialize() { InitializeComponent(); var lastNavState = Preferences.Get("LastNavigationState", string.Empty); if (!string.IsNullOrEmpty(lastNavState)) { await NavigationService.NavigateAsync(lastNavState); } else { await NavigationService.NavigateAsync("MainPage"); } }
Prism的GetNavigationUriPath能直接获取完整导航栈,恢复时用该URI导航即可重建页面结构。
2. 修正CreateWindow重写逻辑
确保返回的窗口已正确赋值Page属性,避免空窗口触发异常:
protected override Window CreateWindow(IActivationState activationState) { var window = base.CreateWindow(activationState); var navigationService = Container.Resolve<INavigationService>(); if (window.Page == null) { var lastNavState = Preferences.Get("LastNavigationState", string.Empty); var targetPage = string.IsNullOrEmpty(lastNavState) ? "MainPage" : lastNavState; window.Page = navigationService.NavigateAsync(targetPage).Result; } return window; }
3. 优化Android配置降低进程销毁概率
- 在
AndroidManifest.xml的<application>标签中开启大内存堆:<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:largeHeap="true"> - 给主Activity设置
singleTask启动模式,避免重复创建进程:<activity android:name="MainActivity" android:exported="true" android:launchMode="singleTask">
注意:android:persistent="true"仅适用于系统级应用,普通应用不要使用,否则可能无法通过应用商店审核。
4. 在Activity层保存/恢复状态
在MainActivity中重写状态保存和恢复方法,确保导航状态在系统回收进程时不丢失:
protected override void OnSaveInstanceState(Bundle outState) { base.OnSaveInstanceState(outState); var navigationService = App.Current.Container.Resolve<INavigationService>(); var navState = navigationService.GetNavigationUriPath(); outState.PutString("LastNavigationState", navState); } protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); if (savedInstanceState != null) { var lastNavState = savedInstanceState.GetString("LastNavigationState"); if (!string.IsNullOrEmpty(lastNavState)) { Preferences.Set("LastNavigationState", lastNavState); } } }
内容的提问来源于stack exchange,提问作者Yevhenii Yerokhin
相关产品推荐
相关产品推荐

