Handle device configuration changes

Apps need to handle changes in device configuration that can happen at run time, for example, screen orientation change, keyboard show or hide, or a change in language setting.

Standard Android behavior is to destroy and recreate the running activity when the device configuration changes, and for activities and fragments to save their state in the onSaveInstanceState method, and restore it in the onCreate or onRestoreInstanceState method. However, it is not possible to save and restore complex map data objects (for example WebMaps or Layers) in this way. As the onSaveInstanceState bundle mechanism is not designed to handle such potentially large objects, objects such as WebMap and Layer do not support the Parcelable interface required to add them to a bundle.

Learn more about handling configuration change in Android apps.

This topic describes three options for dealing with configuration change in your app. Each option has different benefits and drawbacks and may be appropriate in different parts of different apps. Choose the most appropriate option or options for your app. You may find the best approach is to use a combination of these options, as demonstrated in the highlighted samples.

Option 1: Retain fragment instance

Use fragments to host the views in your app, and call setRetainInstance on the Fragment object or objects that display map data. This prevents the fragment from being destroyed when the activity that contains it is destroyed and recreated. The fragment must recreate the MapView it uses to display the map, because the old MapView is associated with the old activity that is destroyed. At this point, you can populate the new MapView with Layer class member variables if they still remain in memory so data will not need to be fetched from the server again. If the layer objects have already been destroyed, the layers will need to be recreated.

This is the recommended option if your app does not use WebMap objects, and if your app uses config-dependent layouts, strings, drawables, dimensions, and so on. It comes at the small cost of the screen going blank for a moment when the MapView is recreated and redisplayed. If your app does use WebMap objects, consider handling orientation changes yourself (option 2) instead.

Samples

The Fragment Management sample uses this option to retain a number of Layer objects as member variables, and populates the MapView using these layers if they still remain in memory. It also recreates all objects (option 3) as a fallback option if the Layer objects are lost because the system destroys the fragment that contains them.

The Portal Featured User Groups sample uses this option to retain Portal, PortalGroup, and PortalItem objects but handles configuration changes itself (option 2) in a different activity to retain a WebMap object. See the Device Configuration Changes section in the description of this sample for further explanation. It also recreates all objects (option 3) as a fallback option if these objects are lost.

Option 2: Handle configuration changes yourself

Configure activities that display map data to handle configuration changes yourself to prevent the system from destroying and recreating these activities when orientation and keyboard configuration changes occur. Add the android:configChanges attribute to the appropriate activity element or elements in the app's AndroidManifest.xml file. For example, the following code sample indicates the activity will manually handle any changes of device orientation, screen size, keyboard type, or accessibility:

AndroidManifest.xml file entry to handle configuration changes manually in an activity

<activity android:name=".ActivityName"
  android:label="@string/app_name"
  android:configChanges="orientation|screenSize|keyboard|keyboardHidden"
  ...
/>

This option can offer a smooth user experience when the configuration changes, because the MapView and any contained objects do not need to be recreated, so there is minimal disruption to what the user sees on the screen.

However, it comes at a significant cost if your app makes extensive use of config-dependent layouts, strings, drawables, dimensions, and so on, as you must add code to the onConfigurationChanged method in your activities to make any required changes to your app when the configuration changes. This process is also likely to be error prone. See Handling The Change in the Android developer documentation for a description of how to handle config changes yourself.

This option is the only way to retain WebMap objects when the configuration changes. A WebMap is attached to the MapView used to display it, and all its data needs to be fetched from the server again if it is passed to a new MapView.

Samples

The Simple Map sample uses this option, as no configuration changes are required by this app if the device orientation changes or the keyboard is shown or hidden.

The Portal Featured User Groups sample uses this option in one activity to retain a WebMap object, in addition to using options 1 and 3 where appropriate. See the Device Configuration Changes section in the description of this sample for further explanation.

Option 3: Recreate all objects

Create new mapping data objects each time your activities are created or recreated. This is the most straightforward option to implement but gives the worst user experience, as the MapView must be entirely recreated. Any server data will have to be fetched each time the activity is destroyed and recreated, which is time consuming and uses more network communications than may otherwise be necessary.

However, all apps should implement this as a fallback option for scenarios where the original objects will be lost. For example, in options 1 and 2, your Fragment and/or Activity may be destroyed by the system if they are pushed into the background and memory resources become low. You'll need to recreate all your objects when your Activity is restarted.

Samples

The Fragment Management sample uses this option as a fallback option (in addition to option 1) if the Layer objects are lost because the system destroys the fragment that contains them.

The Portal Featured User Groups sample uses this option as a fallback option (in addition to option 1 and 2 where appropriate) if portal and WebMap objects are lost.