Android Q, uiMode, and Configuration Changes

If you are a regular follower of my blog posts, I have complete confidence that you are a fine Android app developer and that all of your apps support configuration changes.

However, there seem to be a lot of apps out there that don’t.

In many cases, that is because the apps do not support orientation changes. The UIs are locked to portrait or landscape. Orientation changes are the most common source of configuration changes on phones. The other configuration change triggers are less common, with the second-most common one probably being changing locale. So, some developers think they can skip dealing with configuration changes.

Android Q puts far greater emphasis on the uiMode configuration change, though. That gets invoked whenever the device switches between normal and dark mode. The user might do that manually, and it might kick in when the device battery gets low. It would not shock me if some devices offer other options for automatically toggling into dark mode, just as stock Android 9.0 offers time-based “night light” mode (a blue light filter).

And, if your app does not handle configuration changes properly, your UI will lose context when the device switches between normal and dark mode, as your visible activities and their fragments get destroyed and recreated. Symptoms include:

  • Losing information in your widgets, because that information is not part of automatic saved instance state logic (e.g., enabled status)

  • Forgetting about a dialog, because you are showing it directly instead of using a DialogFragment, so the dialog vanishes after the configuration change

  • Reloading data from disk or the network, because you are not using a ViewModel, retained fragment, or other way to keep that data around across the configuration change

So, even if your UI is locked to a single orientation, please add configuration change support. Android Q gives us another easy way to test configuration changes: add the “Dark Theme” tile to the notification shade, then toggle between normal and dark modes using the tile.

Also, if you are manually managing configuration changes via android:configChanges, there is a good chance you will want to manage uiMode manually as well. For example, if your app involves continuous playback (e.g., a video player), you might not want to interrupt playback just because the device switched between normal and dark mode.