06 June 2012

Detecting your Windows 8 app is running in the background

In Windows Phone life was so simple: when the user put your app in the background, as of version 7.5 the OS effectively froze all threads, timers and whatnot completely automatically. And it was automatically restarted too, if you used fast application switching. That kind of freeloading appeals to my natural programmer’s laziness so I put that to good use. That is, by doing nothing and letting the OS taking care of things.

Enter Windows 8: that has a even more sophisticated multi tasking system that allows things to actually keep running in the background. Excellent for most scenarios, but not if you are writing a game. I am currently porting Catch’em Birds to Windows 8 and observed that although the game music (thankfully) shuts up when the game is put in the background, the birds keep on flying and the timer keeps on running.

Now in App.Xaml.cs there is an OnSuspending method, but that is only called when the application is suspended – i.e., pushed out of memory. This is comparable to the point where a Windows Phone application would tombstone itself. You need to trap another event: VisibilityChanged of the current window.

In the OnLaunchedmethod of App.Xaml.cs, just above the Window.Current.Activate you can add

Window.Current.VisibilityChanged += Current_VisibilityChanged;
That gives a Windows.UI.Core.VisibilityChangedEventArgs which has a boolean Visible property that you can use like this:
void Current_VisibilityChanged(object sender, 
                               Windows.UI.Core.VisibilityChangedEventArgs e)
  System.Diagnostics.Debug.WriteLine("Visibile: " + e.Visible);

I am going to use this to send this event trough the MVVMLight messenger and adapt my game so that is reacts to this event – like in ‘stop the birds, or at least the timer. The OS being more capable actually requires me to do a wee bit more work. No more freeloading ;-)


thinkingIn16Bits said...

Is above "Window.Current.VisibilityChanged" the right place to put "Window.Current.VisibilityChanged" ? I would expect that this shall register the event handler as many times as the method is invoked. Wouldn't it be better to put it below "Window.Current.Content = rootFrame;"

Joost van Schaik said...

@thinkingIn16Bits I am not sure what you mean. I register in OnLaunched in App.Xaml.cs, as far as I am aware of, this is only activated (thus registered) when the app is launched, right?