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

24

最新的app-compat链接是1.1.0

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

对于API 24及以上版本,我使用了ContextWrapper并设置了locale,因此可以正常工作。

我的问题是,如果androidx.appcompat:appcompat:1.1.0是稳定版本,为什么它可以在alphabeta版本中正常工作,而其他人在这里尝试的问题则不行。

我应该等待官方稳定版本再降级到最后一个稳定版本,还是有更有效的方法让Google知道(当然,我知道如何提交错误报告)?


1
是的,这可能是一个 bug。如果你真的不需要版本 1.1.0,那么请降级并等待稳定版本发布。 - Rahul Khurana
1
@RahulKhurana 没错。谢谢伙计。我会这样做的。 - sanjeev
@0101100101 你搞错了...我已经提到过那个链接了,最新的1.1.0版本已经发布了...在alpha和beta版本上它对我有效,但在之后的最新版本1.1.0上却不行。 - sanjeev
是的,你说得对,这个问题不同,但无论如何,我在链接的问题中添加了一个修复程序,你可能会发现有用。 - 0101100101
4个回答

31

编辑:

如果您要继续使用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提供的解决方案这里。

旧答案:

尝试了几个小时后,发现它可能是一个bug。

降级到上一个稳定版本,它可以无缝地工作。

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 提交了一个问题。


2
谷歌库的质量正在发生可怕的变化。我也为此苦苦挣扎了好几个小时。 - Szymon Klimaszewski
2
这在Android 6.0.1 API 23的1.2.0-alpha02后停止工作,尽管他们说已经在 https://issuetracker.google.com/issues/140602653 中修复了:/ - Aba
我更新到androidx.appcompat:appcompat:1.2.0后,applyOverrideConfiguration不再被调用,这又引起了一个问题。 - Rashad.Z
@Rashad.Z 我认为这个问题必须在最新的appcompat版本中修复。 - sanjeev

7

新的应用程序兼容库存在与夜间模式相关的问题,导致在Android 21到25上覆盖配置。

可以通过在调用以下公共函数时应用自己的配置来解决此问题:

public void applyOverrideConfiguration(Configuration overrideConfiguration

对我而言,通过将被覆盖的配置设置复制到我的配置中,这个小技巧就起作用了,但您可以根据需要进行任何其他处理。最好重新将语言逻辑应用于新配置以最小化错误。

@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) - 0101100101
这是负责该问题的函数。由于夜间模式的错误,配置从Android 21覆盖到Android 25。只要在调用super.applyOverrideConfiguration之前应用逻辑即可实现任何逻辑。此外,您可以添加检查Android版本是否介于21和25之间。@sanjeev @ 0101100101 - Jack Lebbos
无法工作。它崩溃并显示以下日志: java.lang.IllegalStateException: getResources() 或 getAssets() 已被调用 at android.view.ContextThemeWrapper.applyOverrideConfiguration(ContextThemeWrapper.java:95) - Shayan_Aryan

2

要使本地化更改与最新的appcompat v1.2.0兼容,请使用以下代码。

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

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

请注意:不要在您的活动中覆盖此方法"applyOverrideConfiguration"。

-2

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"

}

请始终更改设计库中的androidx或其他默认Android库。并在布局代码中强制执行更改,类似于...
<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_views"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            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_width="match_parent"
    android:layout_height="match_parent">

所以其他一些类型的代码在布局上也有所改变...


抱歉,我不太明白您的意思,这与本地化问题有关吗? - sanjeev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接