Search code examples
c#windows-phone-8windows-phone

Static variable initialized in App_Launching suddenly null


Windows Phone 8 project. I have a class that holds a reference to an image. I initialize said reference in the Launching event handler in the app class:

private void Application_Launching(object sender, LaunchingEventArgs e)
{
    TheClass.Load();
}

//Elsewhere...
class TheClass
{
    static private int[] s_Pixels = null;

    static public void Load()
    {
        BitmapImage bi = new BitmapImage(new Uri("/res/image.png", UriKind.Relative));
        bi.CreateOptions = BitmapCreateOptions.BackgroundCreation;
        bi.ImageOpened += OnImageLoaded;
        bi.ImageFailed += OnImageFailed;
    }

    private static void OnImageLoaded(object o, RoutedEventArgs a)
    {
        BitmapImage bi = o as BitmapImage;
        s_Pixels = new WriteableBitmap(bi).Pixels;
    }

    // And consumers call this one:
    static public WriteableBitmap GetImage()
    {
        if (s_Pixels == null)
            SendDebugReport();
    }
}

This code works fo me. And yet I'm getting those debug reports, indicating that s_Pixels is null. I can't reproduce it, but my users obviously can. There's a code path that leads to GetImage() being called without a prior call to Load().

It's Load that's not being called, not that I call Load and OnImageLoaded never happens.

There are no other assignments to s_Pixels anywhere.

I do check for image loading errors. There's an ImageFailed event handler that leaves a log trace. It's never invoked, and why would it be - the image in question is in the app's resources.

How is that even possible? How can a Windows Phone app initialize and load without Launching being invoked?


Solution

  • Application_Launching is only called when your application starts anew. If you send it to the background, and the system eventually tombstones it, and then the user reactivates it, your static data will be gone, but Launching will not be called. Instead, you will get a call to Application_Activated.

    So, basically, you need to run all static initialization both on the Launching and on the Activated methods.

    You can most probably reproduce the problem your users are seeing by forcing the tombstoning of your app with Visual Studio: Check the "Tombstone upon deactivation while debugging" on the Debug tab of your project's options, run the app under debugger, press the Windows key when the app is running, and the switch back to the app.