我需要使用带应用程序上下文和SavedStateHandle
的AndroidViewModel
。我已经使用应用程序上下文使其正常工作,但是我无法添加一个SavedStateHandle
。
这是我现在拥有的,仅使用了应用程序上下文:
// A1. get ViewModel in Fragment
val viewModel = ViewModelProvider(viewLifecycleOwner).get(MyViewModel::class.java)
// A2. MyViewModel derives from my custom BaseAndroidViewModel
class MyViewModel(application: Application) :BaseAndroidViewModel(application)
// A3. BaseAndroidViewModel in turn derives from AndroidViewModel
open class BaseAndroidViewModel(application: Application) : AndroidViewModel(application)
我认为在这个问题中,可能可以将其简化为:
// B1. get ViewModel in Fragment
val viewModel = ViewModelProvider(viewLifecycleOwner).get(MyViewModel::class.java)
// B2. BaseAndroidViewModel in turn derives from AndroidViewModel
class MyViewModel(application: Application) : AndroidViewModel(application)
因此,如果我的MyViewModel
中也有一个SavedStateHandle
,我需要如何修改片段中的调用(示例代码中的B1
行)?我是否需要显式调用工厂SavedStateViewModelFactory
?它看起来会是什么样子?(我还是 Kotlin/Android 的新手,以前从未使用过工厂)
BaseFragment
的getDefaultViewModelProviderFactory
覆盖中有一个轻微的复制和粘贴错误:application
在Fragment
中不是直接可用的。我认为它应该是activity?.application!!
- 您能确认一下吗?是否有更好的方法?所有这些空值处理看起来有点丑陋 ;-) - stefan.at.kotlinrequireActivity().application
,但如果在 Activity 不可用时调用它,那将非常令人失望。ViewModel 应该在onCreate
中初始化,但如果此时 Activity 不可用,则必须在onAttach(Context)
中获取application
... 据我所知,在onCreate
中是可以使用activity
的。 - EpicPandaForceSavedStateHandle
。所以最终我只将SavedStateHandle
作为我的 ViewModel 的第二个参数添加了进去。引用:“当使用 Fragment 1.2.0 或其传递依赖项 Activity 1.1.0 时,ViewModel 实例的默认工厂支持在不需要任何其他配置的情况下向您的 ViewModel 传递适当的 SavedStateHandle。”(来源:https://developer.android.com/topic/libraries/architecture/viewmodel-savedstate)我猜这也包括了我观察到的内容。 - stefan.at.kotlinSavedStateViewModelFactory
设为默认值了?那么你甚至不需要覆盖任何东西。这是个好消息,我会更新帖子的。我之前并不知道这一点。 - EpicPandaForce