onCleared 未在 Fragment 的附加 ViewModel 上调用

onCleared is not being called on Fragment's attached ViewModel

当应用程序进入后台时未调用 ViewModel.OnCleared() 时我偶然发现了一个问题(即使 Don't keep activities 已启用)但我可以看到 Fragment.onDestroy() 实际上正在调用叫。

以下代码可能有什么问题?在这种情况下如何使 ViewModel.OnCleared() 被实际调用?

视图模型:

class ViewModelFirst(application: Application) : AndroidViewModel(application) {

    companion object {
        private const val TAG = "ViewModelFirst"
    }

    init {
        Log.v(TAG, "Created")
    }

    override fun onCleared() {
        super.onCleared()
        Log.v(TAG, "onCleared")
    }
}

片段:

class FragmentFirst : Fragment() {

    companion object {
        private const val TAG = "FragmentFirst"
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        ViewModelProviders.of(this).get(ViewModelFirst::class.java)

        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.v(TAG, "onDestroy")
    }
}

Activity:

class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG = "MainActivity"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction().replace(R.id.container, FragmentFirst()).commit()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.v(TAG, "onDestroy")
    }    
}

自己回答:

这是 com.android.support:appcompat-v7:27.1.0

的错误

如果我使用以下依赖项,我会遇到此问题:

implementation 'com.android.support:appcompat-v7:27.1.0'
implementation "android.arch.lifecycle:extensions:1.1.0"

如果我将 appcompat-v7 的版本更改为 27.1.0 -> 27.0.2,那么 ViewModel.OnCleared() 会按预期工作(当应用程序进入后台时我会接到电话)。

appcompat-v7:28.0.0-alpha1 也有效,看起来这只是 appcompat-v7:27.1.0

的问题

更新(2018 年 6 月)

正如@Akshay 所说,该错误已在 27.1.1 上修复。但并不完全不幸。

以下情况仍未解决:

  1. 已启用 Don't keep activities
  2. 启动应用程序。
  3. 按主页按钮。

在 27.0.2 我在 logcat 有以下输出:

V/ViewModelFirst: Created
V/ViewModelFirst: onCleared
V/FragmentFirst: onDestroy
V/MainActivity: onDestroy

完全正确。

但是在 27.1.1 到 28.0.0-alpha3 我在 logcat 有以下输出:

V/ViewModelFirst: Created
V/FragmentFirst: onDestroy
V/MainActivity: onDestroy

正如我们所见,activity 片段已被销毁,但未通过 onCleared 通知 viewModel。

我怀疑如果 Don't keep activities 将被禁用并且后台的应用程序将在某些时候被 Android 自然卸载(由于另一个应用程序要求大量资源)时间 viewModel.onCleared() 不会被调用,这是非常可悲的。

P.S。我已将代码推送到此处:https://github.com/allco/onClearedInvestigation

并已将此问题报告给 Google 此处:https://issuetracker.google.com/issues/110285295

更新(2018 年 8 月)

28.0.0-rc01 解决了这个问题。耶!

这是支持库 v27.1.0 中的一个问题,已在支持库 v27.1.1 中修复。

之前在 https://issuetracker.google.com/issues/74139250 上报告了一个错误。

请参阅此 link 了解更多详情:https://developer.android.com/topic/libraries/support-library/revisions