通过视图模型在片段之间共享数据

Muh*_*lib 0 android android-viewmodel android-jetpack

根据https://developer.android.com/topic/libraries/architecture/viewmodel 上的“片段之间共享数据”部分,我们被告知在活动范围内创建一个 ViewModel 并在片段之间共享是要走的路.

这是在 ViewModel 中设置值的 Fragment

class MasterFragment : Fragment() {

    private lateinit var itemSelector: Selector

    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
        itemSelector.setOnClickListener { item ->
            // Update the UI
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是使用属性集的细节片段

class DetailFragment : Fragment() {

    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
        model.selected.observe(this, Observer<Item> { item ->
            // Update the UI
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

这是视图模型

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题很简单。假设 MasterFragment 在单击按钮时在 ViewModel 中设置了一个值,在系统杀死我们的应用程序并重新启动它之后访问它时我们将如何恢复该值?

我们的 DetailFragment 不会看到该值,因为我们是在 MasterFragment 中的按钮单击上设置它的。为了更好地理解这个问题,请考虑我们有 Fragment A、B、C 和 D,它们共享一个 ViewModel,其中的值 Fragment AB 和 C 一起计算并将其放置在 ViewModel 中供 Fragment D 访问。

现在,当系统杀死并重新创建我们的应用程序片段 D 时,该值将不可用。

OnSaveInstance 如果不求助于脏代码,也将无法提供太多帮助。对于简单的情况,是的,但是就像 FragmentA B 和 C 一起产生一个值的情况一样,在这种情况下, OnSaveInstance 会出现问题。

OnSaveInstance 应该在 ViewModel 中,但可惜我不认为是这种情况。有任何想法吗?

Vir*_*tel 7

在获取 ViewModel 时,ViewModel 对象的范围是传递给 ViewModelProvider 的 Lifecycle。ViewModel 一直保留在内存中,直到它的范围内的 Lifecycle 永久消失:在活动的情况下,当它完成时,而在片段的情况下,当它分离时。

你可以在这里查看

我的问题很简单。假设 MasterFragment 在 ViewModel 中的 buttonClick 上设置了一个值,那么在系统杀死我们的应用程序并重新启动它之后访问它时,我们如何恢复该值?

如果应用程序被用户或系统杀死或重新启动,则无法恢复该值。

为了解决您从 Activity A、B 和 C 中累积数据并将其显示在 Activity D 中的目的,即使应用程序被终止或重新启动,您可以从以下任意一种方法中选择:
1. SharedPreference
2. 本地数据库或 SQLite
3 . 将数据存储在文件中

我建议您对小数据使用 SharedPreference,对大数据和复杂数据使用 Room。

简而言之,ViewModel 临时存储数据以应对方向变化(无需编写onSaveInstanceState和 的代码onRestoreInstanceState)并在 Activity 和 Fragment 之间共享数据。如果活动被破坏或片段被分离,数据将丢失。