我正在使用View Model体系结构组件来处理UI状态并包含业务逻辑。众所周知,它可以在配置更改后幸存下来,但是在“开发人员”选项中启用了“不保留活动”选项时,将创建一个新的View Model实例。在这两种情况下都将调用onDestroy活动,那么两者之间有什么区别?
我在View模型中维护状态机,并且由于View模型无法幸免,因此在恢复状态机时遇到了问题。我无法使用实例状态,因为它具有复杂的对象。
以下日志来自我尝试过的示例项目。它有一个活动TestActivity
,其中包含一个片段TestFragment
,而TestFragment
包含两个片段TestStateAFragment
和TestStateBFragment
TestActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test)
if(savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.add(R.id.container_fragment_test, TestFragment())
.commitAllowingStateLoss()
}
}
TestFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Timber.i("onViewCreated")
super.onViewCreated(view, savedInstanceState)
if(savedInstanceState == null) {
childFragmentManager.beginTransaction()
.add(R.id.container_state_a, TestStateAFragment.newInstance())
.commitAllowingStateLoss()
childFragmentManager.beginTransaction()
.add(R.id.container_state_b, TestStateBFragment.newInstance())
.commitAllowingStateLoss()
}
}
TestStateAFragment.kt
private val compositeDisposable: CompositeDisposable = CompositeDisposable()
private lateinit var viewModel : TestStateAViewModel
override fun onCreate(savedInstanceState: Bundle?) {
Timber.i("onCreate")
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this, TestStateAViewModelFactory())
.get(TestStateAViewModel::class.java)
Timber.i(viewModel.toString())
}
屏幕旋转:
(TestStateAFragment.kt:101)#onPause: onPause
(TestStateBFragment.kt:66)#onPause: onPause
(TestFragment.kt:72)#onPause: onPause
(TestActivity.kt:45)#onPause: onPause
(TestStateAFragment.kt:105)#onStop: onStop
(TestStateBFragment.kt:70)#onStop: onStop
(TestFragment.kt:76)#onStop: onStop
(TestActivity.kt:50)#onStop: onStop
(TestActivity.kt:23)#onSaveInstanceState: onSaveInstanceState
(TestFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
(TestStateAFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
(TestActivity.kt:54)#onDestroy: onDestroy
(TestStateAFragment.kt:110)#onDestroyView: onDestroyView
(TestStateBFragment.kt:75)#onDestroyView: onDestroyView
(TestFragment.kt:81)#onDestroyView: onDestroyView
(TestStateAFragment.kt:115)#onDestroy: onDestroy
(TestStateBFragment.kt:80)#onDestroy: onDestroy
(TestFragment.kt:86)#onDestroy: onDestroy
(TestFragment.kt:17)#onAttach: onAttach
(TestFragment.kt:18)#onAttach: TestFragment{984b690 (625e084e-68d8-46d6-9527-dfe2694fa5c1) id=0x7f07004c}
(TestFragment.kt:23)#onCreate: onCreate
(TestStateAFragment.kt:30)#onAttach: onAttach
(TestStateAFragment.kt:31)#onAttach: TestStateAFragment{1ff9e9a (f73d9a4a-4fb0-4e1c-b6b0-220941525ae2) id=0x7f07004d}
(TestStateAFragment.kt:39)#onCreate: onCreate
(TestStateAFragment.kt:44)#onCreate: com.example.lifecycleviewmodel.fragment.states.a.TestStateAViewModel@afc805d
(TestStateBFragment.kt:27)#onAttach: onAttach
(TestStateBFragment.kt:28)#onAttach: TestStateBFragment{908b1a7 (a5fa2bce-9b3b-4474-ae2a-0a891f289f65) id=0x7f07004e}
(TestStateBFragment.kt:33)#onCreate: onCreate
(TestActivity.kt:34)#onStart: onStart
(TestFragment.kt:34)#onCreateView: onCreateView
(TestFragment.kt:40)#onViewCreated: onViewCreated
(TestStateAFragment.kt:67)#onCreateView: onCreateView
(TestStateAFragment.kt:73)#onViewCreated: onViewCreated
(TestStateBFragment.kt:44)#onCreateView: onCreateView
(TestStateBFragment.kt:50)#onViewCreated: onViewCreated
(TestFragment.kt:61)#onStart: onStart
(TestStateAFragment.kt:90)#onStart: onStart
(TestStateBFragment.kt:55)#onStart: onStart
(TestActivity.kt:40)#onResume: onResume
(TestFragment.kt:66)#onResume: onResume
(TestStateAFragment.kt:95)#onResume: onResume
(TestStateBFragment.kt:60)#onResume: onResume
不要停止活动:
(TestStateAFragment.kt:101)#onPause: onPause
(TestStateBFragment.kt:66)#onPause: onPause
(TestFragment.kt:72)#onPause: onPause
(TestActivity.kt:45)#onPause: onPause
(TestStateAFragment.kt:105)#onStop: onStop
(TestStateBFragment.kt:70)#onStop: onStop
(TestFragment.kt:76)#onStop: onStop
(TestActivity.kt:50)#onStop: onStop
(TestActivity.kt:23)#onSaveInstanceState: onSaveInstanceState
(TestFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
(TestStateAFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
(TestActivity.kt:30)#onRestart: onRestart
(TestActivity.kt:34)#onStart: onStart
(TestFragment.kt:61)#onStart: onStart
(TestStateAFragment.kt:90)#onStart: onStart
(TestStateBFragment.kt:55)#onStart: onStart
(TestActivity.kt:40)#onResume: onResume
(TestFragment.kt:66)#onResume: onResume
(TestStateAFragment.kt:95)#onResume: onResume
(TestStateBFragment.kt:60)#onResume: onResume
(TestStateAFragment.kt:101)#onPause: onPause
(TestStateBFragment.kt:66)#onPause: onPause
(TestFragment.kt:72)#onPause: onPause
(TestActivity.kt:45)#onPause: onPause
(TestStateAFragment.kt:105)#onStop: onStop
(TestStateBFragment.kt:70)#onStop: onStop
(TestFragment.kt:76)#onStop: onStop
(TestActivity.kt:50)#onStop: onStop
(TestActivity.kt:23)#onSaveInstanceState: onSaveInstanceState
(TestFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
(TestStateAFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
不要继续进行活动:
(TestStateAFragment.kt:101)#onPause: onPause
(TestStateBFragment.kt:66)#onPause: onPause
(TestFragment.kt:72)#onPause: onPause
(TestActivity.kt:45)#onPause: onPause
(TestStateAFragment.kt:105)#onStop: onStop
(TestStateBFragment.kt:70)#onStop: onStop
(TestFragment.kt:76)#onStop: onStop
(TestActivity.kt:50)#onStop: onStop
(TestActivity.kt:23)#onSaveInstanceState: onSaveInstanceState
(TestFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
(TestStateAFragment.kt:55)#onSaveInstanceState: onSaveInstanceState
(TestActivity.kt:54)#onDestroy: onDestroy
(TestStateAFragment.kt:110)#onDestroyView: onDestroyView
(TestStateBFragment.kt:75)#onDestroyView: onDestroyView
(TestFragment.kt:81)#onDestroyView: onDestroyView
(TestStateAFragment.kt:115)#onDestroy: onDestroy
(TestStateBFragment.kt:80)#onDestroy: onDestroy
(TestFragment.kt:86)#onDestroy: onDestroy
2019-09-18 20:30:10.503 31473-31473/com.example.lifecycleviewmodel W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@d382041
(TestFragment.kt:17)#onAttach: onAttach
(TestFragment.kt:18)#onAttach: TestFragment{544b1c5 (625e084e-68d8-46d6-9527-dfe2694fa5c1) id=0x7f07004c}
(TestFragment.kt:23)#onCreate: onCreate
(TestStateAFragment.kt:30)#onAttach: onAttach
(TestStateAFragment.kt:31)#onAttach: TestStateAFragment{ea5f827 (f73d9a4a-4fb0-4e1c-b6b0-220941525ae2) id=0x7f07004d}
(TestStateAFragment.kt:39)#onCreate: onCreate
(TestStateAFragment.kt:44)#onCreate: com.example.lifecycleviewmodel.fragment.states.a.TestStateAViewModel@fa43f72
(TestStateBFragment.kt:27)#onAttach: onAttach
(TestStateBFragment.kt:28)#onAttach: TestStateBFragment{f66bb79 (a5fa2bce-9b3b-4474-ae2a-0a891f289f65) id=0x7f07004e}
(TestStateBFragment.kt:33)#onCreate: onCreate
(TestActivity.kt:34)#onStart: onStart
(TestFragment.kt:34)#onCreateView: onCreateView
(TestFragment.kt:40)#onViewCreated: onViewCreated
(TestStateAFragment.kt:67)#onCreateView: onCreateView
(TestStateAFragment.kt:73)#onViewCreated: onViewCreated
(TestStateBFragment.kt:44)#onCreateView: onCreateView
(TestStateBFragment.kt:50)#onViewCreated: onViewCreated
(TestFragment.kt:61)#onStart: onStart
(TestStateAFragment.kt:90)#onStart: onStart
(TestStateBFragment.kt:55)#onStart: onStart
(TestActivity.kt:40)#onResume: onResume
(TestFragment.kt:66)#onResume: onResume
(TestStateAFragment.kt:95)#onResume: onResume
(TestStateBFragment.kt:60)#onResume: onResume
那么,这两种情况在哪里完全不同,有没有办法确定发生了哪种情况?
答案 0 :(得分:1)
发生配置更改时,Android框架将在您的onRetainNonConfigurationInstance()
上调用Activity
。您可以返回任何想要的对象。然后,Android将销毁您的Activity
并立即创建一个新实例。在新实例的onCreate()
中,您可以调用getLastNonConfigurationInstance()
。如果由于配置更改而重新创建了Activity
,则从onRetainNonConfigurationInstance()
返回的对象将在此处返回。否则,呼叫返回null
。在这种情况下,您可以知道由于配置更改而重新创建Activity
的时间,以及由于其他原因重新启动它的时间。
开发者选项“不要保留活动”通常不需要处理,因为普通用户永远不要启用它。您可以将其用于测试目的,以确保Activity
可以正确恢复,以防万一Android决定杀死它。
实际上,Android通常不会终止个人活动。如果Android需要从后台应用程序中恢复资源,它通常只会终止整个操作系统过程。但是,我最近发现某些情况下,某些设备确实在后台运行Android时确实杀死了个人活动。当用户返回到应用程序时,Android将重新创建Activity
。在这种情况下,您将从null
返回getLastNonConfigurationInstance()
,但是在Bundle
调用中将获得非空onCreate()
,并且还将获得非空{ Bundle
中的{1}}。因此,您应该能够分辨出以下两者之间的区别:
onRestoreInstanceState()
首次创建Activity
实例Activity
实例在Android将其杀死并用户返回后重新创建我不确定您的要求,但是此信息应该会有所帮助。
答案 1 :(得分:0)
由于FragmentActivity在consulNode1
期间存储了它,因此ViewModel可以保留配置更改,而在Activity的配置更改过程中会调用它。我认为当“不保留活动”模式打开时,或者当Android系统回收Activity时,它不属于配置更改的过程。因此,consulNode2
将不会被调用,并且在重新创建Activity之后,ViewModel将无法生存。