【问题标题】:Why my ViewModel is still alive after I replaced current fragment in Android?为什么在我替换 Android 中的当前片段后我的 ViewModel 仍然存在?
【发布时间】:2020-05-31 12:28:57
【问题描述】:

例如,如果我将 'fragmentA' 替换为 'fragmentB',fragmentA 的 'viewModelA' 仍然有效。为什么?

片段的onCreate()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    viewModel = ViewModelProvider.NewInstanceFactory().create(InvoicesViewModel::class.java)
}

视图模型

class InvoicesViewModel : ViewModel() {

init {
    getInvoices()
}

private fun getInvoices() {

    viewModelScope.launch {

        val response = safeApiCall() {
            // Call API here
        }

        while (true) {
            delay(1000)
            println("Still printing although the fragment of this viewModel destroied")
        }

        if (response is ResultWrapper.Success) {
            // Do work here
        }
    }
}
}

这个方法用来替换片段

fun replaceFragment(activity: Context, fragment: Fragment, TAG: String) {
    val myContext = activity as AppCompatActivity
    val transaction = myContext.supportFragmentManager.beginTransaction()
    transaction.replace(R.id.content_frame, fragment, TAG)
    transaction.commitNow()
}

您会注意到协程中的 while 循环仍然可以工作,尽管在将片段替换为另一个片段之后。

【问题讨论】:

  • 请贴一些代码看看你在做什么。
  • @PFuster 添加了代码
  • 您是否正确初始化ViewModel?来自 Android 文档:ViewModelProvider(this).get(InvoicesViewModel::class.java) EDIT 刚刚看到下面的答案

标签: android android-fragments mvvm viewmodel coroutine


【解决方案1】:

检查您是否在 Activity 中创建了 ViewModel,并传递了 Activity 或 Fragment 的上下文。

【讨论】:

  • 我在问题中添加了代码快照,请检查。
【解决方案2】:

这是关于您对ViewModelProvider 的实现。 使用这种方式来创建你的 viewModel。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewModel = ViewModelProvider(this).get(InvoicesViewModel::class.java)
}

通过这种方式,您可以将片段作为视图模型的实时范围。

【讨论】:

  • 但是,这个 ViewModelProviders 目前已弃用 developer.android.com/reference/androidx/lifecycle/…
  • 现在已弃用
  • @MahmoudIbrahim 是的,我现在检查并更新我的答案
  • @MarkKeen 创建 ViewModel 不是一个好主意。视图模型的优点之一是它可以保存您的数据,直到您的范围处于活动状态,并且如果您的屏幕再次创建,您不需要再次获取它们。
  • 太好了,解决了。正是这个问题,谢谢@mahdishahbazi 的回答。但我认为您有一个拼写错误,请从您的答案中删除“新”,因为这是 Kotlin 代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多