【问题标题】:How to access ViewModel from attachBaseContext()?如何从 attachBaseContext() 访问 ViewModel?
【发布时间】:2021-06-23 18:36:05
【问题描述】:

对于我们想要使用应用通过 Play 核心库下载的语言资源的每个活动,我们需要更新基本上下文并通过其配置设置新的语言环境:

override fun attachBaseContext(base: Context) {
  val configuration = Configuration()
  configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
  val context = base.createConfigurationContext(configuration)
  super.attachBaseContext(context)
  SplitCompat.install(this)
}

如您所见,语言是从共享首选项中检索的。然而,使用 MVVM,其中 repository 模式负责处理 Shared Preferences 并且 ViewModel 与它,如何从attachBaseContext() 访问那个ViewModel

尝试从 attachBaseContext() 调用 ViewModel 会返回以下错误:You can’t request ViewModel before onCreate call

【问题讨论】:

    标签: android mvvm sharedpreferences viewmodel google-play-core


    【解决方案1】:

    您无法从override fun attachBaseContext(base: Context) 方法中获取Activity 的ViewModel,因为ActivityViewModelStore 中保留了一个ViewModel 对象(也可以从中恢复)。要获取 ViewModelStore 一个 Activity (AppCompatActivity),请调用 ComponentActivity.getViewModelStore()。方法getViewModelStore() 检查Activity.getApplication() 的值:如果值为空,那么您会收到类似问题中的错误:

    "Your activity is not yet attached to the "
    "Application instance. You can't request ViewModel before onCreate call."
    

    方法Activity.getApplication() 的返回值Activity.mApplication 变量将在attachBaseContext(base: Context) 执行后初始化(来自attach method)。实际上,我们需要访问 Activity 的NonConfigurationInstances 对象,即Activity.getLastNonConfigurationInstance()。在此对象中,活动在配置更改周围保存ViewModelStoreNonConfigurationInstances 对象作为 final Activity 方法 attach 的参数传递(我们不能覆盖它们),方法 attachBaseContext(base: Context) 从中调用,但在 attachBaseContext 方法执行后对象将保存在活动中。

    您可以将 ViewModel 保存在应用程序中,但我认为它没有意义(这是个坏主意)。 MVVM 或MMVM(来自您的回答)如何限制直接使用存储库?看起来这是一个角落案例:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      相关资源
      最近更新 更多