I’ve been working on getting Dark Mode in our app fully supported and I stumbled upon an interesting finding:
The
Application#applicationContext
does not keep information about the theme that you have set viaAppCompatDelegate.setDefaultNightMode()
, only a View or Activitycontext
has this information stored.
After reading through Chris Banes’ articles and watching some great talks about Styles, Themes & Dark Mode, I felt pretty comfortable that I knew quite a bit about the Theming system on Android. However, this particular issue was something that I was not expecting, which is why I decided to document this particular problem I faced.
The Problem
I have the “Dark theme” set on in my system settings, but inside my app I am explicitly setting the theme to light mode (even though my device theme is set to Dark):
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
I have two bitmap resources: one located in drawable
and one located in drawable-night
.
Despite my app theme overriding the mode to “light”, the resource from drawable-night
was loaded instead of the one from thedrawable
folder.
Why was this happening? 🧐
I was using the Application#applicationContext
to load up the Bitmap:
class BitmapLoader(val context: Context) {
override fun loadBitmap(@RawRes resourceId: Int, bitmapConfig: Bitmap.Config): Bitmap? {
val options =
BitmapFactory.Options().apply { inPreferredConfig = bitmapConfig }
return BitmapFactory.decodeResource(
context.resources, resourceId, options
)
}
}
// This class was used in a similar way to the following usage:
val bitmapLoader = BitmapLoader(application.applicationContext)
The Solution
The fix in this case was to use the Activity#context
method or View#context
, instead of Application#applicationContext
.
The lesson here is that the Application#applicationContext
should not be used for retrieving UI resources. The Application
object will only have system-level information and not information that is set by AppCompatDelegate
. AppCompatDelegate
only works on the activity-level.
You need to be very careful of the context you use when obtaining resources that could change based on the theme.
Thanks for reading, if you have any questions or comments — feel free to reach out on Twitter @riggaroo.
Thanks to Chris Banes and Alan Viverette for confirming what I was experiencing is intentional.