Platform compatibility and breaking changes for Windows Phone Silverlight 8.1 apps
July 21, 2014
This topic describes the areas in which Windows Phone Silverlight 8.1 apps behave differently than Windows Phone 8 apps, and describes changes you may need to make to your app after you upgrade it to Silverlight 8.1
After upgrading your app to Silverlight 8.1 you still may find that your app encounters runtime errors that it didn’t before upgrading. There may be APIs that are documented as potentially throwing an exception, but because the exception never occurred during development, your code does not make the call from within a try block. When debugging your upgraded app, keep this in mind and look for unhandled exceptions as a source of new runtime errors. In some cases, you may want to write additional code to handle the exception.
Silverlight 8.1 and Windows Phone 8 apps are terminated when the user uses the Back button to navigate backward past the first page of the app. This is different than the behavior of Windows Phone Store apps, which are paused when the user backs out of them. You can force your app to use the behavior of Windows Phone Store apps by setting PauseOnBack, which causes your app to be suspended when the user navigates backward past the first page of the app.
On Windows Phone 8, the default behavior when the user launches an app from the Apps list or its primary tile is for a new instance of the app to be launched, replacing any existing instance of the app. Developers could override this behavior by modifying the app manifest, described in Enabling Fast Resume in the app manifest file. A Silverlight 8.1 app is always resumed when launched, instead of replacing any running instance. This behavior matches the behavior of Windows Phone Store apps. However, Silverlight 8.1 and Windows Phone 8 apps are terminated when the user uses the Back button to navigate backward past the first page of the app. After an app is terminated this way, any launch of the app will result in a new instance being created.
Windows Phone 8 apps can continue to run in the background after the user navigates away from the app under certain conditions. This feature is not available for Silverlight 8.1 apps. If you need this feature, you should continue to use a Windows Phone 8 app. For more information, see Running location-tracking apps in the background for Windows Phone 8.
For a managed Windows Phone 8 ScheduledTaskAgent to be able to access Silverlight 8.1 features, it runs on the modern execution stack, which is converged with Windows. This uses a different CPU quota mechanism than Windows Phone 8. In some cases, a Silverlight 8.1 background agent might find that it gets less CPU time than it did previously. If that happens, the app may choose to call RequestAccessAsync(). This will increase the CPU quota given to the agent.
In Silverlight 8.1, managed background agents (periodic, background audio, and VoIP) run on top of Windows Runtime background tasks. If you have two or more VoIP, background audio, or periodic background agents, you must specify the task to be launched in a separate host, declared in the AppX manifest.
The AudioPlayerAgent and AudioStreamingAgent classes, which supported background audio playback for Windows Phone 8 apps, are not supported in Silverlight 8.1. If you want to support background audio playback, you can continue to use a Windows Phone 8 app or create a Windows Phone Store app, which supports new background audio APIs.
The WalletAgent, which supports Near Field Communication (NFC) in Windows Phone 8 apps, is not supported in Silverlight 8.1. If you want to support NFC you must use the new NFC APIs and implement NFC background tasks.
You declare a background task with an Extension element in the app manifest. When doing this, you should not include the Executable attribute. The following syntax is permitted.
<Extensions> <Extension Category="windows.backgroundTasks" EntryPoint="AgHost.BackgroundTask"> ... </Extension> </Extensions>
In Windows Phone 8, you can specify a DLL as an OutOfProcessServer for ActivatableClasses. This is acceptable in the WMAppManifest.xml, but a DLL is not acceptable in the AppX manifest, and it fails schema validation. The AppX manifest requires an EXE and there's no way to specify an EXE host with a given DLL server. The app must be updated to use an EXE as the OutOfProcessServer. Apps using Windows Runtime OutOfProc activation must use a custom host and remove the run-time statements that explicitly register the Windows Runtime classes or the activation factories from within their app code.
If your Windows Phone 8 app uses resource files to provide localized text for tiles, described in How to build a localized app for Windows Phone 8, your tiles will continue to function properly when you upgrade to Silverlight 8.1 as long as you continue to use the Microsoft Push Notification Service framework for your app’s push notifications. This is the default behavior when upgrading. If you choose instead to move to the Windows Notification Service, which is used by all Windows Phone Store apps, the localized text will be inaccessible and will not be displayed on your tiles. For information about choosing the push notification service for your app, see Choosing MPNS or WNS for a Windows Phone Silverlight 8.1 app.
Silverlight 8.1 apps can’t use managed Windows Runtime components or managed Windows Runtime background tasks. Silverlight 8.1 apps can continue to use Windows Phone 8 background agents that have been upgraded with the rest of the app to Silverlight 8.1. Silverlight 8.1 apps also can use native Windows Runtime components, or they can build a managed component as a regular class library instead.
When you create a Portable Class Library (PCL) and reference it from both a Silverlight 8.1 app and a Windows Runtime Component project that implements a background task for that app, you cannot use the .NET classes in the Microsoft HTTP Client Libraries or Microsoft Compression NuGet packages. If you share a dependency on these packages across both project types, or on a third-party portable library that uses these packages, errors will occur. Instead, to create a PCL that can be shared between these project types, use the Windows Runtime classes in the Windows.Web.Http.HttpClient namespace and classes in the Windows.Storage.Compression namespace in your portable library. To do this, the portable library must target Windows Phone 8.1 and Silverlight 8.1. Optionally, target Windows 8.1. For more information, see the Supported Features section of Cross-Platform Development.
The DefaultTask element in the WMAppManifest.xml specifies the app page that will be displayed when the app is initially launched. In Windows Phone 8, this element is optional, but Silverlight 8.1 apps must specify a default task. For more information, see Tasks element.
You can include a ScreenResolution element in the app manifest for a Windows Phone 8 app to specify the screen resolutions supported by the app. The Windows Phone Store uses this information to hide the app from devices with unsupported screen resolutions. This feature is not supported for Silverlight 8.1 apps.
On Windows Phone 8.1 devices, the size of the ApplicationBar in terms of Silverlight’s logical pixels is not constant across different screen sizes/densities. In a app, the DefaultSize and MiniSize properties on ApplicationBar report the occluded size. In a Windows Phone 8 app, they continue to report the same values as on a Windows Phone 8 device.
On larger screens, an opaque ApplicationBar consumes less space, leaving more for the app to display content. The DefaultSize and MiniSize properties on ApplicationBar can be used at run time to determine how much space is occluded.
If your app uses Windows.Storage.KnownFolders.CameraRoll to access the pictures library on the device, you need to add the Pictures Library capability in your Silverlight 8.1 app’s Package.appxmanifest file or you will get an “access denied” error when attempting to access the property. For more info about the manifest files for Silverlight 8.1 apps, see Upgrade Windows Phone 8 apps to Windows Phone Silverlight 8.1.
Windows Phone 8 apps use ProcessCommittedLimit or ApplicationMemoryUsageLimit to determine their current memory usage. This property always has a value of 0 when accessed from a Silverlight 8.1 app. Silverlight 8.1 app should instead use the properties of the Windows.System.MemoryManager to manage app resources. To get the current memory usage of your app, use the Windows.System.MemoryManager.AppMemoryUsage property.
An app should not call WaitForPendingFinalizers() on the main Silverlight thread because there is no guarantee that the method will terminate.
For Silverlight 8.1 apps, the foreground app runs in the Application Single-Threaded Apartment (ASTA). This is a change from Windows Phone 8 foreground apps, which use the Multithreaded Apartment (MTA) model. If your app calls CoInitializeEx from the main Silverlight thread and it returns RPC_E_CHANGED_MODE, your app will need to provide marshalling support for any types that are not meant to run on the Silverlight main thread. Alternatively, you could define their types to implement IAgileObject.
Background agents continue to use the MTA model.
The background task host for Silverlight 8.1 apps calls RunWithActivationFactories(IGetActivationFactory) during the initialization sequence. This is a change from Windows Phone 8. If you upgrade your app from Windows Phone 8 to Silverlight 8.1 and your background task calls RunWithActivationFactories, CO_E_ALREADYINITIALIZED will now be returned from the call. You should update your code to handle this error. Your app should ignore the error and continue.
In Windows Phone 8, if a VoIP background agent crashes or is forcibly terminated for any reason, the foreground VoIP app can continue to run. In Silverlight 8.1 apps, if a VoIP background agent crashes or is forcibly terminated for any reason, this will also terminate the foreground VoIP app. This is because VoIP apps on Silverlight 8.1 are managed at the package level, not the individual process level, and both the background and foreground parts of the app belong to the same app package.
On the Windows Phone OS 8.0, apps that play background music by using the MediaEngine from Microsoft Media Foundation are not required to call the MFStartup function to initialize the platform before instantiating the MediaEngine. On the Windows Phone OS 8.1 and later, however, apps are required to call the MFStartup function to initialize the platform before instantiating the MediaEngine, as documented in the description for the IMFMediaEngineClassFactory::CreateInstance method. If you don't call MFStartup, the MediaEngine starts in a shutdown state and playback isn't possible. Before the app closes, remember to call the MFShutdown function one time for every previous call to MFStartup.
In Windows Phone 8 apps, you can specify in the app manifest file (in the ScreenResolutions element) that your app supports some but not all of the available screen resolutions. In Windows Phone Silverlight 8.1 apps, you have to support all screen resolutions.
When you create tile assets at design time, choose a resolution that scales well across different resolutions.
When you load image assets at run time, load assets appropriate for the current resolution, or load high-resolution assets and let the platform scale the assets to the current resolution.
The ScreenResolutions element still exists in the Xml of the WMAppManifest.xml file, but is no longer displayed in Manifest Designer, and is ignored when you publish your Silverlight 8.1 app.
This section lists the changes in Silverlight APIs between Windows Phone 8 and Silverlight 8.1.
In Windows Phone 8, Panorama does not call Measure(Size) for collapsed items. This has the consequence that items initially added as Collapsed are not displayed when their visibility is set to Visible until some other event triggers a call to MeasureOverride(Size). This is not the case in Silverlight 8.1
In Silverlight 8.1, Panorama handles PanoramaItem objects uniformly, whether they were explicitly added or generated through databinding. The SelectedItem property will return the associated data item. Also, the SelectionChanged event is now raised for databound PanoramaItem objects. In Windows Phone 8, it is not.
Web Browser control
The HTML5 project template has been modified for Silverlight 8.1. The included CSS file (phone.css) contains definition for width, which was set to values that would not scale well with newly supported device resolutions. In Silverlight 8.1, the value "device-width" has been added and will return correct values based on device size and resolutions.
In the Windows Phone 8 WebBrowser control, the default value of IsScriptEnabled is false, which caused frustration among developers because it’s not obvious that it needs to be set to true for the control to work correctly. In Silverlight 8.1 the tools have been updated to set that value to true by default at design time.
In Silverlight 8.1, the User Agent string used by the WebBrowser control has been updated to include the string “WebBrowser/8.1” to enable web sites to identify clients using the control.
In the Windows Phone 8.1 WebBrowser control, the ScriptNotify event has changed to be an asynchronous event. It was previously a synchronous event in Windows Phone 8 Silverlight apps. If a Windows Phone 8 Silverlight app is run on Windows Phone 8.1, the behavior change in ScriptNotify from synchronous to asynchronous will cause apps to execute differently.
This section lists several small changes in behavior that were made to the Common Language Runtime (CLR) between the release of Windows Phone 8 apps and Silverlight 8.1. If your app uses the following APIs, you may need to make some small adjustments to your app after upgrading to Silverlight 8.1.
Absolute paths are not supported for Load(String) and Load(String). This includes resource paths, such as “;/component”, which were previously supported in Windows Phone 8. If your existing code uses resource paths, you will need to update your code for Silverlight 8.1. As a workaround, you can either add your resource file as Content and load it using a relative path or get the embedded file stream and then create XDocument from the stream.
The Uri constructor has been updated to support the ms-app schema. For example:
Uri myUri = new Uri("ms-app://s-1-15-2-123456789-3297869828-1925210038-511929589-250463720-3381006342-2815560950");
The M:System.Uri.ToString() method has been updated to fix some mishandled URL encoding.
new Uri("http://test.com/?MpnToken=67%3d").ToString(); // previous result: "http://test.com/?MpnToken=67%3d" // new result: "http://test.com/?MpnToken=67="
FromAsync(Func<AsyncCallback, Object, IAsyncResult>, Action<IAsyncResult>, Object) was changed to special-case when CompletedSynchronously returned true, assuming that if it did return true, it didn’t need to do any synchronization to complete the Task returned from FromAsync(Func<AsyncCallback, Object, IAsyncResult>, Action<IAsyncResult>, Object), since the Task wouldn’t have been given back to the caller yet. Note that this only affects profiling, not the app directly.
In Windows Phone 8, ForEach(Action<T>) allows a collection to be changed and still allows for iteration through the rest of the collection. In Silverlight 8.1, code changes have been made to throw an exception when the collection is changed while still being enumerated.
Sort() has been optimized to use introspective sort instead of quick sort.