Reputation: 53
When I use Datastore to make the function that can switch language dynamically in my App, I found a error :
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
my code is easy:
open class BaseActivity : AppCompatActivity() {
override fun attachBaseContext(newBase: Context) {
lifecycleScope.launch(Dispatchers.Main) {
var context = newBase
val language = withContext(Dispatchers.IO) {
DataStore.read(context, DataStore.KEY_LANG)
}
context = Language.changeLanguage(context, language ?: Language.ZH)
super.attachBaseContext(context)
}
}
}
Language.changeLanguage will return a context that update the local:
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
fun changeLanguage(context: Context, lang: String): Context {
val configuration = context.resources.configuration
configuration.setLocale(getLocal(lang))
return context.createConfigurationContext(configuration)
}
I debug my App and found that the code cant reach super.attachBaseContext(context)
and finished.
I dont know the reason but i guess that because the coroutines.
Upvotes: 4
Views: 1571
Reputation: 25603
The problem is that Application
is a ContextWrapper
and after attachBaseContext
returns it presumes the underlying context has been properly set.
Since you defer calling super.attachBaseContext
to the end of the coroutine this method will not be called until the coroutine gets the chance to run (because happens on Dispatchers.Main
this would probably be after normal initialization is done since that happens synchronously), breaking the contract of the method.
Practically you have three options:
context.getApplicationContext()
.Upvotes: 1