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

Android中如何重启Activity应用新Locale实现多语言切换?

解决方案

1. 修复LanguageUtils的setLocale方法

当前方法仅设置了config.setLocale,在API 26+系统中需兼容多区域设置,同时保留原有配置参数(如方向、密度),修改后的代码如下:

class LanguageUtils {

    static String getCurrentLanguage(Context context) {
        SharedPreferences prefs = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE);
        return prefs.getString("lang", "en");
    }

    static void saveLanguage(Context context, String language) {
        SharedPreferences prefs = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE);
        prefs.edit().putString("lang", language).apply();
    }

    static Context setLocale(Context context, String lang) {
        Locale locale = new Locale(lang);
        Locale.setDefault(locale);

        Resources resources = context.getResources();
        Configuration config = new Configuration(resources.getConfiguration());

        // 适配不同API版本的区域设置
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            config.setLocales(new LocaleList(locale));
        } else {
            config.setLocale(locale);
        }

        // API 21+使用createConfigurationContext,避免废弃方法
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            return context.createConfigurationContext(config);
        } else {
            resources.updateConfiguration(config, resources.getDisplayMetrics());
            return context;
        }
    }
}

2. 所有Activity必须重写attachBaseContext

Application的上下文配置不会自动传递给Activity,需创建基类Activity统一处理语言设置:

open class BaseComposeActivity : ComponentActivity() {
    override fun attachBaseContext(newBase: Context) {
        val currentLang = LanguageUtils.getCurrentLanguage(newBase)
        val updatedContext = LanguageUtils.setLocale(newBase, currentLang)
        super.attachBaseContext(updatedContext)
    }
}

你的Compose Activity需继承该基类:

class MainActivity : BaseComposeActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            // 你的Compose内容
        }
    }
}

3. 优化语言切换后的Activity重启逻辑

原重启方式可能存在上下文传递问题,修改MyApplication的方法确保新Activity使用最新配置:

class MyApplication : Application() {

    override fun attachBaseContext(base: Context) {
        val currentLang = LanguageUtils.getCurrentLanguage(base)
        val newContext = LanguageUtils.setLocale(base, currentLang)
        super.attachBaseContext(newContext)
    }

    fun setAppLanguage(activity: Activity, language: String) {
        LanguageUtils.saveLanguage(activity, language)
        
        // 启动应用入口Activity,清除旧任务栈
        val intent = activity.packageManager.getLaunchIntentForPackage(activity.packageName)
        intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
        activity.startActivity(intent)
        activity.finish()
    }
}

4. 验证资源文件配置

确保对应语言的资源目录和文件存在且名称一致:

  • res/values/strings.xml(默认英文)
  • res/values-pl/strings.xml(波兰语)

示例资源内容:

<!-- values/strings.xml -->
<string name="someString">Hello</string>

<!-- values-pl/strings.xml -->
<string name="someString">Witaj</string>

核心说明

  • Jetpack Compose的stringResource依赖当前Activity的上下文配置,因此每个Activity必须单独处理语言设置。
  • API 21+使用createConfigurationContext是官方推荐的updateConfiguration替代方案,避免使用废弃API。
  • 重启时清除任务栈可确保新启动的Activity完全加载最新语言资源,避免旧上下文残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:29:55