You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

API 18下Android应用无法切换语言求助

解决Android API18应用内语言切换失效的问题

嘿,我碰到过好多次这种API18及以下版本语言切换失效的问题,这是因为Android在7.0(API24)前后的语言配置机制有很大差异,旧版本需要手动处理Context的资源更新才行!下面给你一步步拆解解决方案:

核心原因

API24之前,系统不会自动将自定义的语言配置应用到已创建的Context和Activity中,必须手动更新资源配置并重启Activity才能生效;而API24及以上可以通过AppCompatDelegate.setApplicationLocales轻松实现全局语言切换。

具体解决步骤

1. 自定义Application类,全局配置语言

所有组件的Context都会继承Application的配置,所以先在这里统一处理:

public class MyApp extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        // 从SharedPreferences读取已保存的语言设置(比如"zh"代表中文,"en"代表英文)
        String savedLang = getSharedPreferences("app_config", MODE_PRIVATE)
                .getString("selected_language", "zh");
        super.attachBaseContext(updateLocaleContext(base, savedLang));
    }

    private Context updateLocaleContext(Context context, String langCode) {
        Locale targetLocale = new Locale(langCode);
        Locale.setDefault(targetLocale);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // API24+使用createConfigurationContext
            Configuration config = context.getResources().getConfiguration();
            config.setLocale(targetLocale);
            config.setLayoutDirection(targetLocale);
            return context.createConfigurationContext(config);
        } else {
            // API23及以下手动更新资源配置
            Resources res = context.getResources();
            Configuration config = res.getConfiguration();
            config.locale = targetLocale;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                config.setLayoutDirection(targetLocale);
            }
            res.updateConfiguration(config, res.getDisplayMetrics());
            return context;
        }
    }
}

别忘了在AndroidManifest.xml中注册这个Application:

<application
    android:name=".MyApp"
    ...>
    ...
</application>

2. 让所有Activity继承BaseActivity,确保语言配置生效

每个Activity创建时都会调用attachBaseContext,这里重写它来应用语言配置:

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void attachBaseContext(Context newBase) {
        String savedLang = getSharedPreferences("app_config", MODE_PRIVATE)
                .getString("selected_language", "zh");
        super.attachBaseContext(updateLocaleContext(newBase, savedLang));
    }

    // 和Application中的updateLocaleContext方法完全一致,也可以抽取成工具类复用
    private Context updateLocaleContext(Context context, String langCode) {
        Locale targetLocale = new Locale(langCode);
        Locale.setDefault(targetLocale);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Configuration config = context.getResources().getConfiguration();
            config.setLocale(targetLocale);
            config.setLayoutDirection(targetLocale);
            return context.createConfigurationContext(config);
        } else {
            Resources res = context.getResources();
            Configuration config = res.getConfiguration();
            config.locale = targetLocale;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                config.setLayoutDirection(targetLocale);
            }
            res.updateConfiguration(config, res.getDisplayMetrics());
            return context;
        }
    }
}

3. 编写语言切换的工具方法,切换后重启Activity

切换语言后必须重启Activity栈,让新的配置生效:

public class LanguageUtils {
    public static void switchAppLanguage(Context context, String targetLang) {
        // 保存语言设置到SharedPreferences
        SharedPreferences.Editor editor = context.getSharedPreferences("app_config", Context.MODE_PRIVATE).edit();
        editor.putString("selected_language", targetLang);
        editor.apply();

        // 重启应用的主Activity,清除旧栈
        Intent intent = new Intent(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
        if (context instanceof Activity) {
            ((Activity) context).finish();
        }
    }
}

关键注意点

  • 资源文件检查:确保你已经创建了对应语言的资源目录,比如values-en(英文)、values-zh(中文),并放入对应的字符串资源。
  • 避免系统语言覆盖:API18中如果系统语言变化,可能会重置你的配置,所以每次Activity创建时都要通过attachBaseContext重新应用自定义语言。
  • 测试场景:测试时要完全退出应用再重新打开,确保Application的配置生效。

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

火山引擎 最新活动