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 上修复。但并不完全不幸。
以下情况仍未解决:
- 已启用
Don't keep activities
。
- 启动应用程序。
- 按主页按钮。
在 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
当应用程序进入后台时未调用 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 上修复。但并不完全不幸。
以下情况仍未解决:
- 已启用
Don't keep activities
。 - 启动应用程序。
- 按主页按钮。
在 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