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

Android ViewModel中getString无法获取正确本地化值求助

解决ViewModel中本地化字符串不更新的问题

问题根源

你在ViewModel中使用getApplication<Application>().resources获取字符串,但Application级别的Context配置不会随Activity的attachBaseContext修改而同步更新——即使重启Activity,Application实例可能仍保留旧的Locale配置,导致拿到的是未本地化的旧字符串。


解决方案1:同步更新Application的Locale配置

在Application类中也设置Locale,确保全局Resources都使用最新语言:

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        setupAppLocale()
    }

    private fun setupAppLocale() {
        // 从SharedPreferences读取选中的语言
        val prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
        val selectedLang = prefs.getString("selected_language", "en") ?: "en"
        
        val locale = Locale(selectedLang)
        Locale.setDefault(locale)
        
        val config = resources.configuration
        config.setLocale(locale)
        config.setLayoutDirection(locale)
        // 更新Application的Resources配置
        resources.updateConfiguration(config, resources.displayMetrics)
    }
}

同时修改重启应用的代码,确保彻底重启(清除任务栈,让Application重新初始化):

editor.apply()
// 获取应用启动Intent
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
}
launchIntent?.let { startActivity(it) }
finish()

解决方案2:由UI层负责传递本地化字符串

避免ViewModel直接操作Resources,转而由Activity/Fragment(持有正确Locale的Context)获取字符串后传递给ViewModel:

ViewModel代码:

class MyViewModel : ViewModel() {
    val textLiveData = MutableLiveData<String>()

    // 接收UI层传入的本地化字符串
    fun updateLocalizedText(text: String) {
        textLiveData.postValue(text)
    }
}

Activity代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 初始化时传递本地化字符串
    viewModel.updateLocalizedText(getString(R.string.text))
}

// 若支持动态切换语言(无需重启),可在Configuration变化时更新
override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    viewModel.updateLocalizedText(getString(R.string.text))
}

解决方案3:在ViewModel中创建本地化ContextWrapper

如果ViewModel必须自行获取字符串,可以每次创建一个基于当前Locale的ContextWrapper,避免依赖Application的旧配置:

class MyViewModel(application: Application) : AndroidViewModel(application) {
    private fun getLocalizedContext(): Context {
        val prefs = application.getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
        val selectedLang = prefs.getString("selected_language", "en") ?: "en"
        
        val locale = Locale(selectedLang)
        val config = application.resources.configuration.apply {
            setLocale(locale)
            setLayoutDirection(locale)
        }
        // 创建带最新Locale的Context
        return application.createConfigurationContext(config)
    }

    fun loadLocalizedText() {
        val localizedText = getLocalizedContext().getString(R.string.text)
        textField.postValue(localizedText)
    }
}

内容的提问来源于stack exchange,提问作者Maifee Ul Asad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:48:30