更新到 androidx.appcompat:appcompat:1.1.0 后的语言更改问题

Posted

技术标签:

【中文标题】更新到 androidx.appcompat:appcompat:1.1.0 后的语言更改问题【英文标题】:Language change issue after updating to androidx.appcompat:appcompat:1.1.0 【发布时间】:2020-01-13 23:13:53 【问题描述】:

最新app-compat的链接是1.1.0。

在将我的应用升级到最新的app-compat 后,我的语言设置在 API 24 以下的手机上停止工作(粗略地说,肯定不适用于 API 21 及以下版本)。

对于 API 24 及更高版本,我使用了 ContextWrapper 并设置了 locale 因此有效。

我的问题是,如果androidx.appcompat:appcompat:1.1.0 是稳定版本,为什么它在alphabeta 版本中对我有用,不像这里的其他版本以及我尝试过的问题。

After updating AppCompat library to appcompat:1.1.0-alpha03 Locale configuration is not working anymore Change Locale not work after migrate to Androidx - 讨论 alpha 和 beta(我正在使用最新的稳定版本 1.1.0

我是否应该再次等待官方稳定版本并降级到 最后一个稳定版本或者哪个是让谷歌的有效方法 知道是否有(当然,我知道提交错误)?

【问题讨论】:

是的,这可能是一个错误。如果你真的不需要版本1.1.0,那就降级等待稳定版发布 @RahulKhurana 对。谢了哥们。会这样做。 @0101100101 你错了.. 我已经提到过那个链接,最新的1.1.0 来了.. 它在 alpha 和 beta 版本上对我有用,但在最新版本 1.1 上不起作用.0 之后。 是的,你是对的,问题是不同的,但无论如何我在链接的问题中添加了一个修复程序,你可能会觉得有用 【参考方案1】:

编辑:

要继续使用 1.1.0 版,请将其添加到您的 attachBaseContext 下方:

Kotlin 解决方案:

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) 
    if (overrideConfiguration != null) 
        val uiMode = overrideConfiguration.uiMode
        overrideConfiguration.setTo(baseContext.resources.configuration)
        overrideConfiguration.uiMode = uiMode
    
    super.applyOverrideConfiguration(overrideConfiguration)

Java 解决方案:

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) 
    if (overrideConfiguration != null) 
        int uiMode = overrideConfiguration.uiMode;
        overrideConfiguration.setTo(getBaseContext().getResources().getConfiguration());
        overrideConfiguration.uiMode = uiMode;
    
    super.applyOverrideConfiguration(overrideConfiguration);

如果您不需要升级到最新的appCompat,请检查 旧答案。否则使用@0101100101提供的解决方案 here.

旧答案:

花了几个小时尝试后,才知道这可能是一个错误。

降级到最后一个稳定版本,它可以完美运行。

dependencies 
    implementation 'androidx.appcompat:appcompat:1.0.2'   //************ DO NOT UPGRADE LANGUAGE ISSUE on API 23 and below *******************//
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
....

同时,我已经向 Google https://issuetracker.google.com/issues/140880275提出了一个问题

【讨论】:

这对 Google 库的质量有什么影响。我也为此苦苦挣扎了一个小时。 这在1.2.0-alpha02 for Android 6.0.1 API 23 之后停止工作,尽管他们说它已在issuetracker.google.com/issues/140602653 中修复:/ 我更新到 androidx.appcompat:appcompat:1.2.0 并且不再调用 applyOverrideConfiguration 这又导致了问题 @Rashad.Z 我认为这个问题必须在最新的 appcompat 版本中修复。【参考方案2】:

与夜间模式相关的新应用兼容库中存在一个问题,导致覆盖 android 21 到 25 上的配置。 这可以通过在调用此公共函数时应用您的配置来解决:

public void applyOverrideConfiguration(配置覆盖配置

对我来说,这个小技巧通过将设置从被覆盖的配置复制到我的配置而奏效,但你可以做任何你想做的事情。最好将您的语言逻辑重新应用到新配置中以最大程度地减少错误

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) 
if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT <= 25) 
        //Use you logic to update overrideConfiguration locale
        Locale locale = getLocale();//your own implementation here
        overrideConfiguration.setLocale(locale);

super.applyOverrideConfiguration(overrideConfiguration);

【讨论】:

没有帮助,因为此代码更改使所有复数字符串与java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.icu.util.ULocale.getBaseName()' on a null object reference at android.icu.impl.PluralRulesLoader.getRulesIdForLocale(PluralRulesLoader.java:166)一起崩溃 这是负责该问题的函数。由于夜间模式错误,配置从 android 21 覆盖到 android 25。只要在调用super.applyOverrideConfiguration 之前应用它,您就可以实现任何您想要的逻辑。此外,您可以添加检查 android 版本是否在 21 和 25 之间。@sanjeev @ 0101100101 不起作用。我因日志崩溃:java.lang.IllegalStateException: getResources() 或 getAssets() 已在 android.view.ContextThemeWrapper.applyOverrideConfiguration(ContextThemeWrapper.java:95) 处调用【参考方案3】:

要使用最新的 appcompat v1.2.0 进行区域设置更改,请使用以下代码。

(1) 将此函数添加到您的基础活动中。

@Override
protected void attachBaseContext(Context newBase) 
    super.attachBaseContext(setDefaultLanguage(newBase)); // Selected app language.
    applyOverrideConfiguration(newBase.getResources().getConfiguration());

注意:请勿在您的活动中覆盖此方法“applyOverrideConfiguration”。

【讨论】:

【参考方案4】:

Android x 已经支持这种类型的库...

dependencies 
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation "com.google.android.material:material:1.1.0-alpha09"


请始终在设计库或其他 som 默认 android 库中更改 androidx。

和强制改变布局代码类似...

<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_views"
            android:layout_
            android:layout_
            android:layout_gravity="center"
            android:clipToPadding="false"
            android:padding="2dp" />


<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_>

所以更多其他一些类型代码在布局中发生变化......

【讨论】:

抱歉,我没能联系到您,这是否与语言环境问题有关?

以上是关于更新到 androidx.appcompat:appcompat:1.1.0 后的语言更改问题的主要内容,如果未能解决你的问题,请参考以下文章

华为悦盒刷机更新到35% 左右就显示更新失败?

git 更新代码到本地

华为手机无法高更新到安卓12

GitLab更新代码到新分支

从版本 3 更新到 4 时,Flyway 更新不会迁移 schema_version 表

git如何更新到指定版本,然后再更新到最新版本