It is a non-traditional configuration change. By "non-traditional", I mean that it cannot be blocked by android:configChanges
— your activity will be destroyed and recreated whether you like it or not.
If you have Configuration
objects from before and after the change, you can determine that this scenario occurred by calling diff()
on the newer
Configuration
to compare it to the older one:
val diff = resources.configuration.diff(vm.originalConfiguration)
Log.d("WallpaperCCTest", "matches CONFIG_ASSETS_PATHS? ${(diff.toLong() and 0x80000000) != 0L}")
Here, vm.originalConfiguration
points to the older Configuration
, and we get the current Configuration
from the Resources
object. (diff.toLong() and 0x80000000) != 0L
will evaluate to true
if a wallpaper change or something similar triggered the configuration change. There are other edge cases for this — this whole "unblockable configuration change" thing came about when Sony got Google to add support for runtime resource overlays (RROs) back in 2017. So, some of those "change the system theme" apps might trigger this same unblockable configuration change.
As Nguyễn Hoài Nam notes, you can detect this from onConfigurationChanged()
of a custom Application
. Or, have your viewmodel hold onto the previous Configuration
and compare it with the current one in onCreate()
of your activity.
I have more on this issue in this blog post. AFAIK, there is no way to opt out of this configuration change, so if your app was designed to avoid configuration changes, you may be out of luck.
android:configChanges="orientation|uiMode|mcc|mnc|locale|keyboard|keyboardHidden|navigation|screenLayout|fontScale|screenSize|smallestScreenSize"
– NephogramlayoutDirection
,touchscreen
, anddensity
in that list. While none of those would really fit, you could try adding those and see if it changes your behavior. I forget what Logcat logs around configuration changes, but you might find something there too. BTW, what device are you testing on? – OratoricalonConfigurationChanged()
in this activity, use debugging or logging to see if it is being called. If it is, then there is some new config change type that is not documented, and we'd need to figure out what that is. If it is not being called... that's bad. – OratoricalonConfigurationChanged()
is called only when we have the rightconfigchanges
flag set in the manifest. So no callback happens. The restart also happens on the emulator(API Sv2), so it is definitely Android 12 specific issue. – NephogramonConfigurationChanges
from the Application (which will be called for all such changes, regardless of the Manifest). The flag "assetsSeq" is updated. A demo here: lensdump.com/i/gmpwWA . I used the built-in Wallpaper App, and Pixel 4 running Android 12. – DrankApplication
andonConfigurationChanged()
! I included your tip in my answer and in an update to my blog post on this. Thanks for pointing that out! – Oratorical