添加许多模块时,语言环境的更改确实起作用

问题描述

当有许多模块时,语言环境可以正常工作。

上下文:

  • 我们使用Crowdin(此lib在上下文上方应用包装器)

  • 只有一个模块时,该应用程序才能完美运行

  • 使用Appcompat:1.2

  • “更改语言环境”有效时

但是,当我在app添加新模块时,更改区域设置确实起作用。 implementation project(":newmodule")

单个模块何时

何时多模块

  • BaseContext = ContextThemeWrapper

Activity扩展了 BaseActivity

class MainActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        Crowdin.forceUpdate(context = this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
open class BaseActivity : AppCompatActivity() {
    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(Crowdin.wrapContext(Localization.wrap(context = newBase)))
    }
}
class Localization(base: Context) : ContextThemeWrapper(base,R.style.AppTheme) {
    companion object {

        fun wrap(context: Context,language: String = "es",country: String = "MX"): ContextThemeWrapper {
            var ctx = context
            val config = context.resources.configuration

            if (language != "") {
                val locale = Locale(language,country)
                Locale.setDefault(locale)
                config.setLocale(locale)
                // Used setLayoutDirection for RTL and LTR
                config.setLayoutDirection(locale)
                ctx = context.createConfigurationContext(config)

            }

            return Localization(ctx)
        }
    }
}

解决方法

说明

问题与Appcompat有关。根据{{​​1}}的版本,有两种不同的修复程序。由于您使用的是AppCompat,因此您必须实施该版本。

1.2.0最终删除了语言环境,因为实际上ContextThemeWrapper包装了ContextWrapper。请参见@@ AppCompatDelegateImpl.java line 368的实现。还要在388480行。

AppCompatDelegateImpl

此问题的解决方法是像这样在基本活动中改写try { ContextThemeWrapperCompatApi17Impl.applyOverrideConfiguration( (android.view.ContextThemeWrapper) baseContext,config); return baseContext; } catch (IllegalStateException e) { if (DEBUG) { Log.d(TAG,"Failed to apply configuration to base context",e); } }

getDelegate

您还需要以下类(请参见:Change Locale not work after migrate to Androidx)。

private var baseContextWrappingDelegate: AppCompatDelegate? = null

override fun getDelegate() = baseContextWrappingDelegate ?: BaseContextWrappingDelegate(super.getDelegate()).apply {
    baseContextWrappingDelegate = this
}

参考文献

  1. https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java#368

  2. Change Locale not work after migrate to Androidx

  3. https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java#368