sdk

Android 12 forces an activity rebuild on every wallpaper change

If your app suddenly loses state on a phone running Android 12, the user may have just swapped their wallpaper. A behaviour change described on the Commonsware blog confirms that Android 12 forces activities to restart when the wallpaper changes, and unlike a regular configuration change there is no opt-out.

That detail matters because most Android teams treat configuration changes as a known quantity. Activity recreation on rotation, locale change or theme switch is documented, testable and avoidable with the android:configChanges manifest attribute. The wallpaper case breaks that assumption.

Quick take:

  • Android 12 recreates activities when the wallpaper changes, similar to a configuration change.
  • The recreation is not cancellable via android:configChanges.
  • The behaviour is tied to runtime resource overlay (RRO) machinery, documented by Sony since 2017.
  • A configuration bit, ActivityInfo.CONFIG_ASSETS_PATHS (0x80000000), is set in the diff.
  • OnConfigurationChanged() is not called on the affected activity.
  • The behaviour was surfaced in an AOSP commit, discussed by Commonsware and follower cketti.

Why this is different from a normal config change

In most cases, an Android developer can list which configuration items their activity handles itself in the manifest. Anything not listed gets a clean restart, but anything listed skips the restart entirely. According to Commonsware, the AOSP commit behind this feature takes the unusual step of recreating activities without offering that escape hatch. The reasoning traces back to runtime resource overlays, which are how OEMs and the system push theme changes. Wallpaper changes ride on that same pipeline, so Android treats them like a forced overlay push.

The practical fallout: you cannot declare android:configChanges="assetsPaths" and call it a day. The system will still kill and rebuild your activity.

Detecting that a wallpaper change hit you

The reference post shows a workable pattern. Hold a reference to the original Configuration object in a ViewModel, then compare it against the new one in onCreate() using Configuration.diff(). The bit you care about is CONFIG_ASSETS_PATHS, exposed in source as 0x80000000. If the bitmask test comes back true, the recreation was almost certainly triggered by a wallpaper or overlay change.

A second route, pointed out by commenter Nguyễn Hoài Nam and noted in the article, is to override onConfigurationChanged() in a custom Application subclass. That callback fires for any config change, so you still need the diff() trick to separate wallpaper events from rotation or font-scale changes. Either way, save the latest Configuration and compare against the previous one rather than the original, as the original author recommends for production code.

Our analysis

For most app teams this is a tail-risk event. Wallpaper changes are rare, and the recreation behaves like any other config change, so a ViewModel and savedInstanceState will cover most state. The friction shows up in three places.

First, anything that depends on long-lived resources opened in onCreate, like a camera session, a Bluetooth socket or a heavy media decoder, will now tear down more often than expected. Second, custom theme engines that watch resources directly will see fresh overlays after the restart, which is the point of the feature but can confuse caching logic. Third, analytics and crash reporting pipelines will get a small bump in synthetic lifecycle churn; make sure your dashboards can filter it.

The occasional hiccup the original tester saw, where the wallpaper changed but the activity was not recreated roughly one time in ten, is worth noting. It suggests Android 12 has not fully smoothed this path. Build in a tolerance for both outcomes rather than assuming the recreation is guaranteed.

A scenario: shipping a wallpaper-aware activity

Say you run a media player with an in-app theme that pulls accent colours from a resource overlay. Pre-Android 12, you would never worry about wallpaper swaps during a listening session. Now, a user changes their wallpaper, your activity rebuilds, and the player needs to come back exactly where it was. Store the playback position and the last overlay snapshot in the ViewModel, reload the overlay in onCreate based on the new Configuration, and log a counter tagged "wallpaper_recreate" so support can spot users who hit this path repeatedly. Use Configuration.diff() against the saved bitmask rather than the original configuration; that aligns with the pattern the reference post recommends for production code.

Checklist for affected apps

  • Confirm whether your activity relies on android:configChanges for any overlay-related flags, and remove that assumption.
  • Persist a Configuration snapshot in your ViewModel and diff it on every onCreate.
  • Treat CONFIG_ASSETS_PATHS as a first-class signal in your recreation logging.
  • Audit camera, Bluetooth, media and graphics resources for teardown costs.
  • Add a wallpaper-change scenario to your QA matrix on a Pixel image running Android 12.

What to watch next

Watch the next Android 12 preview drops for any change to the AOSP commit. Google has shipped behaviour like this and walked it back when developers complained. Until then, stop relying on android:configChanges for overlay-like changes, add a CONFIG_ASSETS_PATHS check to your recreation handling, and budget for one extra rebuild in any QA matrix that covers theming.

Key takeaways

  • Treat Android 12 wallpaper changes as a forced, non-cancellable activity recreation.
  • Detect it with Configuration.diff() and the CONFIG_ASSETS_PATHS bit.
  • Audit long-lived resources and media sessions for surprise teardowns.

Frequently asked questions

Can I opt out of Android 12 activity recreation on wallpaper change?

No. According to Commonsware's write-up of the AOSP commit, android:configChanges does not cover this case and apps cannot revoke consent.

How do I detect that a recreation was caused by a wallpaper change?

Save the previous Configuration and call diff() against the current one, then test for the CONFIG_ASSETS_PATHS bit (0x80000000). A custom Application subclass can also intercept onConfigurationChanged(), but you still need the diff to isolate the cause.

Does the activity get onConfigurationChanged() during a wallpaper swap?

The reference post states it is not called on the affected activity. Detection has to happen in onCreate() of the new instance.

Why does Android 12 use runtime resource overlays for wallpapers?

The mechanism is the same one Sony documented for runtime resource overlays in 2017. Wallpaper changes ride on that pipeline, which is why the recreation is enforced rather than optional.

Related