在 viewmodel 中获取字符串资源

Posted

技术标签:

【中文标题】在 viewmodel 中获取字符串资源【英文标题】:Get string resources in viewmodel 【发布时间】:2021-10-13 20:00:12 【问题描述】:

我需要在 TextView 中显示百分比值,例如“15 %” 我通过这种方式在 viewModel 中执行此操作,并且可以正常工作:

                    perfusionIndexValue.postValue(
                        list.lastOrNull()?.perfusionIndex?.takeIf 
                            it != PerfusionIndex.NO_DATA
                        ?.value?.toString().orEmpty() + " %"
                    )

但如果我用资源来做:

                    perfusionIndexValue.postValue(
                        list.lastOrNull()?.perfusionIndex?.takeIf 
                            it != PerfusionIndex.NO_DATA
                        ?.value?.toString().orEmpty() + Resources.getSystem().getString(R.string.pi_percent)
                    )

我明白了

io.reactivex.rxjava3.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | android.content.res.Resources$NotFoundException: String resource ID #0x7f0e0081

我如何设置像“15 %”这样的文本

【问题讨论】:

你为什么不只是传递上下文来获取你的字符串? 什么意思?我只是一名初级开发人员,正在学习 无论此方法是什么,都将上下文作为参数,然后使用 context.getString(R.string.pi_percent) 调用此方法时无法将上下文作为参数发送 为什么?如果没有对上下文的某种引用,您如何期望获得资源? 【参考方案1】:

在你的情况下,我看到你需要这里的上下文。

但是,Fragment 或 Activity 的上下文不应传递到 ViewModel。仅使用 Application Context 来获取资源,...或与 ViewModel 中的 Application 相关的东西。

在这里,如果您没有使用 Hilt(或 Dagger),那么您应该将 ViewModel() 替换为 AndroidViewModel(application),如下所示:

class MyViewModel(application: Application): AndroidViewModel(application) 
    ...

如果使用 Hilt,您可以通过如下 @ApplicationContext 注解注入应用程序上下文,而无需扩展 AndroidViewModel()

@HiltViewModel
class MyViewModel @Inject constructor(
    @ApplicationContext private val context: Context
): ViewModel() 


这里我注意到当使用 Hilt 将 Application Context 注入 ViewModel 时。将应用程序上下文注入 ViewModel 时,您将看到有关内存泄漏的警告。这是最近的 Hilt 版本中的警告,但我测试了 Profiler 并且没有泄漏。

您可以通过以下方式在 ViewModel 中以字符串资源的形式获取资源:

val myText = context.getString(R.string.your_string_id)

【讨论】:

在这种情况下,当我使用...+ application.getString(R.string.pi_percent) 时,我得到java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources() on a null object reference。该资源存在,但我尝试与其他资源并获得相同【参考方案2】:

使用以下内容从 viewmodel 中的资源中获取字符串 -

String s = getApplication().getString(R.string.pi_percent);

【讨论】:

在这种情况下我得到java.lang.NullPointerException 确保字符串是在资源文件中定义的,并且在 getstring 中你使用了正确的值。

以上是关于在 viewmodel 中获取字符串资源的主要内容,如果未能解决你的问题,请参考以下文章

Android Jetpack - ViewModel

Android Jetpack - ViewModel

Android Jetpack - ViewModel

Android ViewModel 不断初始化 ArrayList

我应该如何在 Android 的 viewModel 中获取 Resources(R.string)(MVVM 和数据绑定)

MVVM你到底由多少秘密