.NET MAUI Android 中重开应用为何仍复用原 Window?
数据小陈
结论
两个应用的差异与后台服务有关。第一个应用的后台服务仍在运行,因此上滑移除任务后,应用进程没有结束,原来的 App 对象和 _window 字段也仍然存在。重新打开应用时,CreateWindow 检查到 _window 不为空,便返回原来的 Window。
为什么会出现这种情况
_window 是 App 实例的字段。只要进程和 App 实例还在运行,这个字段就会保留。上滑移除任务本身不能说明进程已经终止,后台服务可能让进程继续运行。再次进入应用时,如果回到的还是原进程,应用会沿用原来的对象状态,包括当前页面。
进程结束后,应用重启时会创建新的 App 实例,字段也会重新初始化。此时 CreateWindow 会创建新的 Window。若要在进程重建后恢复页面,应使用应用状态恢复或持久化机制,不能依赖内存中的 _window。
如何确认
可以在 App 构造函数和 CreateWindow 中记录进程与对象信息,也可以在后台服务的启动、停止逻辑中记录生命周期事件。例如:
_logger.WriteLog($"App created: {Environment.ProcessId}");
protected override Window CreateWindow(IActivationState? activationState)
{
_logger.WriteLog($"CreateWindow: pid={Environment.ProcessId}, windowIsNull={_window is null}");
if (_window is not null)
return _window;
_window = new Window(_shell);
return _window;
}
重新打开应用后,对照 PID、App 构造日志和后台服务日志。如果 PID 和 App 实例没有变化,说明应用仍在原进程中运行,并复用了原来的 Window。如果进程已经重启,原来的 _window 字段就不会保留。
排查与处理
检查后台服务是否仍在运行,以及它的停止条件是否符合预期。如果希望上滑移除任务后服务也停止,应根据服务类型和应用需求,在相应的生命周期或服务逻辑中明确处理停止。具体做法取决于服务实现,题目没有提供足够信息来确定应使用哪种 API。
如果服务需要继续在后台运行,应用进程和内存状态可能会保留,这与复用原 Window 的现象一致。若要在应用重新启动时恢复到之前的页面,即使进程已被系统回收,也应单独保存并恢复导航状态。
备注:内容仅供参考。
