在我的应用程序中,每当我的应用程序关闭时,我都需要进行一些异步清理。理想情况下,我想要一个可以跨平台工作的解决方案,但现在我想让它专门在 Android 上工作。我从 MAUI 应用程序生命周期知道,应在应用程序关闭时调用 OnDestroy,因此它似乎是放置此函数的正确位置,但它似乎并未执行。奇怪的是,如果我删除异步调用,同步调用似乎工作正常。下面是一些代码来说明:
在我的App.xaml.cs中
public partial class App: Application
{
//... some other code here
private JoinableTaskContext _joinableTaskContext = new JoinableTaskContext();
protected override Window CreateWindow(IActivationState? activationState){
Window window = base.CreateWindow(activationState);
window.Destroying += Window_Destroying;
return window;
}
private void Window_Destroying(object? sender, EventArgs e){
/* Wrapping the async call in a joinableTaskFactory to avoid using async void in
the method signature*/
_ = _joinableTaskContext.Factory.RunAsync(async () =>
{
await CleanupOnDestroyAsync();
});
// Some synchronous call to stop a ForegroundService that uses intents.
}
private async Task CleanupOnDestroyAsync(){
await myService.Cleanup();
}
}
我也尝试过在 MAUI-Android 本机 OnDestroy 中使用此代码,但这也不起作用。
我对如何解决这个问题有什么想法吗?
这是可靠的服务器应用程序通信的一种可能的设计。
服务器
解决方案:为每个客户端设置一些最大超时。如果服务器在这段时间内没有收到客户端的消息,则终止会话并执行任何清理。
超时的时间应该取决于保留每个会话的“成本”,以及处理来自客户端的额外数据包(表示它们仍处于活动状态)的成本。可能是从几分钟到一天的任何时间。
一个简单的实现是运行定期作业来检查所有打开的会话,关闭任何超出超时的会话。
应用程序
依赖应用程序关闭代码运行是不安全的。特别是在 Android 上,每个供应商都会调整操作系统。
设计您的应用程序,以便每当它进入后台时,它都会执行任何必要的操作,即使应用程序再也没有机会运行代码。
例如,Android:使用 onSaveInstanceState() 保存简单、轻量级的 UI 状态包含以下语句:
要保存持久数据,例如用户首选项或数据库数据,请在您的活动位于前台时抓住适当的机会。如果没有这样的机会出现,请在 onStop() 方法期间保存持久数据。
应用程序需要定期与服务器通信,这样就不会触发超时。跟踪您上次向服务器发送消息的时间;如有必要,使用计时器发送虚拟消息。每当发送任何消息时重置计时器。
如果通信中断,下次客户端与服务器对话时,服务器可能已经终止会话。客户端和服务器端都需要应对这种情况;建立新会话,而无需用户再次输入登录信息。 “令牌”可能会有所帮助。 [登录时,应用程序会收到一个仅在该设备上有效的令牌,有效期为 12 小时。]
根据您的具体情况:
除了定期发送消息(当应用程序位于前台时)之外,还可以考虑在应用程序进入后台以及返回前台时发送消息。
服务器可以使用它来调整超时。例如,如果用户正在输入数据,则可能会延长超时,希望用户返回应用程序以完成他们正在做的事情。 [或者,应用程序可能只是在本地保存部分输入的数据,因此即使服务器出错,也可以从用户上次停下的地方继续。]