You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android首次调用AppCompatDelegate.setApplicationLocales忽略configChanges致Activity重建

应用内语言偏好首次设置时Activity被强制重建的问题及临时解决方法

我按官方文档实现了应用内语言偏好功能:用户首次打开应用时,先进入语言选择Activity,选完语言后调用以下代码通知系统语言变更:

// 该代码在onCreate()之后的某个时机调用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
  val selectedLanguageIso = "en"
  val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(selectedLanguageIso)
  AppCompatDelegate.setApplicationLocales(appLocale)
}

为避免语言变更时重建Activity,我在Manifest中给LanguageActivity添加了配置:

<activity
    android:name=".LanguageActivity"
    android:screenOrientation="portrait"
    android:configChanges="layoutDirection|locale"/>

但仅首次调用AppCompatDelegate.setApplicationLocales时,系统会忽略这个配置,依然重建Activity,导致页面闪烁,之后才跳转到下一个页面。后续手动更改语言时,该配置能正常生效,不会触发重建。

补充背景:我关闭了自动区域设置存储,所以首次启动应用时Android没有预设语言,必须手动设置,这可能和问题有关:

<service
    android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
    android:enabled="false"
    android:exported="false">
    <meta-data
        android:name="autoStoreLocales"
        android:value="false" />
</service>

请问有没有人遇到过同样的问题?


临时解决方案

我在首个Activity的ViewModel中通过InitializePerAppLanguageUseCase提前初始化语言设置,避免首次调用时的重建问题:

ViewModel代码

init {
    initPerAppLanguage()
    //...其他初始化逻辑
}

private fun initPerAppLanguage() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        initializePerAppLanguage() // 调用下面的UseCase
    }
}

UseCase代码

/**
 * 检查是否需要初始化应用语言设置
 *
 * 由于首次调用`AppCompatDelegate.setApplicationLocales`时,系统会忽略Manifest中的`android:configChanges="layoutDirection|locale"`配置,
 * 导致首次打开应用时Activity重启,所以需要手动提前初始化一次语言设置,让API处于"已初始化"状态,后续调用就不会再触发重建。
 *
 * @see AppCompatDelegate.setApplicationLocales
 */
class InitializePerAppLanguageUseCase(
    private val defaultDeviceLanguage: String, // 对应Locale.getDefault().language
    private val appSettings: AppSettings
) {

    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
    operator fun invoke() {
        
        if (!appSettings.isBoardingDone()) {
            // SupportedLanguages是应用支持的语言列表
            if (SupportedLanguages.languages.contains(defaultDeviceLanguage)) {
               setSelectedLanguage(defaultDeviceLanguage)
            } else {
                // 如果设备语言不在支持列表中,默认回退到英文
               setSelectedLanguage("en")
            }
        }
    }

    private fun setSelectedLanguage(isoCode: String) {
        val localeListCompat = LocaleListCompat.forLanguageTags(isoCode)
        AppCompatDelegate.setApplicationLocales(localeListCompat)
    }

}

内容的提问来源于stack exchange,提问作者JacksOnF1re

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:17:43