How to detect if a user has closed a winrt applica

2019-04-13 23:42发布

What is a reliable (and immediately) way to detect if a user has closed the app with ALT-F4 or the close-gesture?

3条回答
老娘就宠你
2楼-- · 2019-04-14 00:13

According to the Application Lifecycle documentation there is no way to detect this event (See the section under "App close"). This type of state can be managed best using the ApplicationData class.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-04-14 00:20

Not really an exact answer to my specific question, but a way which solved my concrete problem for which I posted my question. Maybe it helps someone else:

Register to Window.CoreWindow.VisibilityChanged:

Window.Current.CoreWindow.VisibilityChanged += CoreWindow_VisibilityChanged;

If the visibility has changed to false, this may be due to the closing of the app. Take care, the event will also fire for many other reasons, such as window changes via ALT-Tab:

 void CoreWindow_VisibilityChanged(CoreWindow sender, VisibilityChangedEventArgs args) {
        if(!args.Visible){
           // Action here
        }
 }

Please note: I suspect that MS has explicitely not provided an event which I was looking for, because heavy operations exactly at the moment the user closes the app will result in a less fluid user experience. However I think there are eligible cases where such an event makes sense and therefore people will use workarounds such as the one I provide here. If you use this or another workaround, take care to not create heavy load to the system.

查看更多
混吃等死
4楼-- · 2019-04-14 00:33

There are no doubt scenarios where you don't want to save state all the time in case the app is suspended. Wouldn't this be called "polling" (which is kinda bad and wasteful in other ways)? In my scenario, I have a timer that tracks time remaining, which is part of the state of the app, but I don't want to store this on every tick.

So, to do this properly, you'll need to:

  1. Track VisibilityChanged (as the original poster stated)
  2. Track Unloaded (whenever you navigate Back from the page, etc)
  3. Track when the page has been unloaded so you don't save stale cached pages that might be hanging around

To elaborate more on #3 above - I found that if I navigated forward from A -> B, then back to A, then to B again, I would end up with another cached page B hanging around. Then when the user left the app, I would get multiple VisibilityChanged events fired, some of these including old cached pages that I thought would have been destroyed but were not.

Here's the code that worked for me:

public void MyPage() // Constructor
{
  Loaded += (sender, e) =>
  {
    if(!m_isLoaded)
    {
      m_isLoaded = true;

      Window.Current.CoreWindow.VisibilityChanged +=
          OnVisibilityChanged;
    }
  };

  Unloaded += async (sender, e) => 
  {
    if (m_isLoaded)
    {
      m_isLoaded = false;

      Window.Current.CoreWindow.VisibilityChanged -= 
          OnVisibilityChanged;

      await SaveStuff();
    }
  };
}

protected void OnVisibilityChanged(object sender,
  Windows.UI.Core.VisibilityChangedEventArgs e)
{
  if (!e.Visible && m_isLoaded)
  {
    var dontAwait = SaveStuff();
  }
}

// Called whenever the page is unloaded and state needs to be saved.
protected async Task SaveStuff()
{
  await ThreadUtility.voidTask();
}

// Set to false when the page is unloaded (paused).
private bool m_isLoaded = false;
查看更多
登录 后发表回答