0

I have a project that needs to support in-app multi-languages changes.

And I am using the 'androidx.appcompat:appcompat:1.1.0' library.

I use this code to change default locale of App

For Android API level >= 24

@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, locale: Locale): Context {

    Locale.setDefault(locale)

    val configuration = context.resources.configuration
    configuration.setLocale(locale)

    return context.createConfigurationContext(configuration)
}

For Android API level < 24

private fun updateResourcesLegacy(context: Context, locale: Locale): Context {

    Locale.setDefault(locale)

    val resources = context.resources
    val configuration = resources.configuration
    configuration.locale = locale

    resources.updateConfiguration(configuration, resources.displayMetrics)
    return context
}

And I call this method on base activity by override attachBaseContext like this:

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(LocaleManager.setLocale(newBase!!))
}

It works perfectly on Android API level >= 24, but doesn't work below API level 24, I have found out a solution at enter link description here

override fun applyOverrideConfiguration(cfgOverride: Configuration?) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
        Build.VERSION.SDK_INT < Build.VERSION_CODES.O
    ) {
        // add this to fix androidx.appcompat:appcompat 1.1.0 bug
        // which happens on Android 5.x ~ 7.x
        resources
    }
    super.applyOverrideConfiguration(cfgOverride)
}

It resolved by simply calling getResources() in Activity.applyOverrideConfiguration().

Can Anyone explain why the issue can be fixed by this solution?

sergiy tikhonov
  • 4,961
  • 1
  • 10
  • 27
Eric Lam
  • 1
  • 1

1 Answers1

0

The source code for getResources() in appcompat 1.1.0 is the following

@Override
public Resources getResources() {
    if (mResources == null && VectorEnabledTintResources.shouldBeUsed()) {
        mResources = new VectorEnabledTintResources(this, super.getResources());
    }
    return mResources == null ? super.getResources() : mResources;
}

So it seems like that mResources field's initialization is key here

Alex Timonin
  • 1,872
  • 18
  • 31