在 Android 上的 .NET MAUI 中使用哪些 LifeCycleEvents?

Joh*_*ing 4 android maui

我有一个视图(带有 ViewModel,都是单例),可以读取和写入文本文件。我希望它以受控的方式打开和关闭,并试图找出在毛伊岛应用程序生命周期中应该发生这种情况的位置。

在正常操作中,我假设应该在 OnAppearing 中打开它并在 OnDisappearing 中关闭它。

但是,如果应用程序移至后台并被终止,则不会触发视图的 OnDisappearing。

它确实会触发 OnPause,因此我可以在此处关闭文件并在 OnResume 上重新打开它,但为了简单起见,我宁愿不使用这些文件(尽管如果推荐,我会这样做)。

我的问题是:当应用程序被用户杀死(即放入后台并刷走)时是否会触发任何事件。如果应用程序被终止,我的文本文件会被整齐地刷新并关闭吗?有谁有更好的方法来做到这一点的建议。我是毛伊岛的新手,可能缺少一些基本的东西。

Too*_*eve 7

“当应用程序被用户杀死时是否会触发任何事件?”

不。您的应用程序代码当时没有机会运行。

Deactivated正如您所发现的,应用程序生命周期(例如或OnPaused)和页面生命周期(Appearing/ )之间存在一些脱节Disappearing

这是 Android 本身的基础,无论是否使用毛伊岛。在 Android 上,应用程序消失之前唯一保证发生的事件是OnPaused;Maui 应用程序的Deactivated事件在 Android 活动OnPaused被调用时运行。

不幸的是OnPaused,之后您的应用程序可能无法运行任何其他代码。你在设计一切时都必须考虑到这一点。

无论您的应用程序显示哪个页面或弹出窗口,或者它位于什么中间,您的“应用程序停用”代码都负责保存需要保留的任何信息。

下面是处理这种情况的一种概念性方法。


“如果应用程序被终止,我的文本文件会被整齐地刷新并关闭吗?”

不。不幸的是,没有标准机制可以为您执行此操作。
您有责任根据用户在应用程序中已完成/正在执行的操作来跟踪需要进行哪些“清理”。

考虑定义public class BasePage : ContentPage一个类,它有一些管理它的方法。让您的页面继承自BasePage.

一个例子:

// In App.xaml.cs:
protected override void OnDeactivated()
{
  CurrentPage?.SaveData();
  ...
}


private static BasePage CurrentPage;
public static void PageAppearing(BasePage page)
{
  CurrentPage = page;
}
public static void PageDisappearing(BasePage page)
{
  // Null CurrentPage, but skip that if has already changed to a different page.
  // (Fixes a bug on some XForms implementations; haven't tested whether this is still an issue in Maui.)
  if (ReferenceEquals(CurrentPage, page)
    CurrentPage = null;
}

Run Code Online (Sandbox Code Playgroud)
public class BasePage : ContentPage
{
  // NO "InitializeContext". No XAML. Each subclass does that.
  public BasePage(){ }

  protected override void OnAppearing()
  {
    base.OnAppearing();
    App.PageAppearing(this);
  }
  protected override void OnDisappearing()
  {
    App.PageDisappearing(this);
    base.OnDisappearing();
  }

  public virtual void SaveData() {}
}
Run Code Online (Sandbox Code Playgroud)
public partial class MyTextEditPage : BasePage
{
  public override void SaveData()
  {
    ... code to save text file being edited ...
  }
}
Run Code Online (Sandbox Code Playgroud)

Deactivated我在/中做的第一件事OnPaused是设置一个标志:(DidPause = true;指声明private static bool DidPause;)。Activated我检查/中的标志OnResume,以了解应用程序在进入后台后仍在继续(但没有被杀死)。

接下来,有一些机制来保存“可能已更改”的数据(又名“脏标志”设置在它们上),但尚未保存到本地文件。拯救他们。(如果有更改的信息尚未成功发送到服务器,那就更复杂了。我首先在本地保存;之后做什么超出了本答案的范围。)

第三,暂停或关闭应用程序在后台时不需要运行的任何内容。


在 中OnResumeif (DidPause) { DidPause = false; ... }用于恢复任何关闭或暂停的内容的代码。

在这种情况下,无论显示什么页面都应该仍然显示。保存数据只是一种预防措施,以防应用程序永远不会回来。

else { ... }(DidPause not set):应用程序第一次启动,或者被杀死后。

  • 感谢 ToolmakerSteve 的全面回复。这正是我需要知道的以及更多。这是我问的第一个毛伊岛问题,但在过去几天里使用了您对其他问题的答复。非常感激。 (2认同)