How to disable features in apps for lower-memory phones for Windows Phone 8

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

If you create an app to run on a lower-memory device, but the app uses features that consume too much memory or you have used a generic background agent, you can detect the memory working set of the device running the app, and then disable the background agent or other memory-intensive features. This topic shows you an example of how to do this.

To detect the memory limit and change app behavior

  1. Declare a property to hold a value that indicates whether or not the device is a lower-memory device. Typically you would store this value in app settings.

    private static bool isLowMemDeviceValue;
    public static bool IsLowMemDevice
    {
        get
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains("IsLowMemDevice"))
                isLowMemDeviceValue = (bool)IsolatedStorageSettings.ApplicationSettings["IsLowMemDevice"];
            return isLowMemDeviceValue;
        }
        set {
            if (value != IsLowMemDevice)
                IsolatedStorageSettings.ApplicationSettings["IsLowMemDevice"] = value;
        }
    }
    
  2. Check the app memory limit for the device. Do this by calling GetValue(String), passing ApplicationWorkingSetLimit. This method returns a long value that indicates the app memory limit for the device.

  3. Check to see whether the value returned from GetValue(String) method is less than 90 MB (94371840). If it is, the device is a lower-memory device.

  4. Wrap the call to GetValue(String) in a try/catch block. It’s possible the user has not upgraded their device to the latest version of the Windows Phone operating system, which means this call is not supported on their device and an ArgumentOutOfRangeException could occur.

Note

Some calls to GetValue(String) require the device identity capability, ID_CAP_IDENTITY_DEVICE, and this capability is added during ingestion if you use the DeviceExtendedProperties class in your application. However, if you use the GetValue(String) method to get the ApplicationWorkingSetLimit you can opt out of the device identity capability by removing it from the app manifest prior to app ingestion and it will not be added back in during the ingestion process.

  1. Depending on the results of the GetValue(String) method, set the property declared in the first step. The following code shows an example of performing steps 2–5 when the app launches.

    private void Application_Launching(object sender, LaunchingEventArgs e)
    {
        try
        {
            // Check the working set limit and set the IsLowMemDevice flag accordingly.
            Int64 result = (Int64)DeviceExtendedProperties.GetValue("ApplicationWorkingSetLimit");
            if (result < 94371840L)
                MainPage.IsLowMemDevice = true;
            else
                MainPage.IsLowMemDevice = false;
        }
        catch (ArgumentOutOfRangeException)
        {
            // Windows Phone OS update not installed, which indicates a 512-MB device.
             MainPage.IsLowMemDevice = false;
        }
    }
    
  2. Use the stored value to vary the code path and to exclude features that would exceed the memory limit or that are not supported on a lower-memory device. The following code shows the OnNavigatedPage method. The code checks to determine whether the device is a lower-memory device, and displays a different UI if it is. This prevents the background agents from running.

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        if (IsLowMemDevice)
            ShowMemPanel();
        else
        {
            periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
            if (periodicTask != null)
            {
                PeriodicStackPanel.DataContext = periodicTask;
            }
            resourceIntensiveTask = ScheduledActionService.Find(resourceIntensiveTaskName) as ResourceIntensiveTask;
            if (resourceIntensiveTask != null)
            {
                ResourceIntensiveStackPanel.DataContext = resourceIntensiveTask;
            }
            ignoreCheckBoxEvents = false;
        }
    }
    
    private void ShowMemPanel()
    {
        // Hide the agent panels and show a simple panel with a textblock instead.
        // The user will not be able to start the background agents.
        MemTextBlock.Text = "Mem usage: " + DeviceStatus.ApplicationPeakMemoryUsage +
            "/" + DeviceStatus.ApplicationMemoryUsageLimit;
        MemStackPanel.Visibility = Visibility.Visible;
        PeriodicStackPanel.Visibility = Visibility.Collapsed;
        ResourceIntensiveStackPanel.Visibility = Visibility.Collapsed;
        ignoreCheckBoxEvents = true;
    }
    

See Also

Other Resources

Developing apps for lower-memory phones for Windows Phone 8

Background agents for Windows Phone 8