进程死亡时的导航图范围 ViewModel
Navigation graph scoped ViewModel on Process Death
当我尝试在我的 Android 应用程序中处理进程死亡时,我注意到范围限定为导航图的 ViewModel 在从进程死亡中重新创建时崩溃了。下面是 ViewModel 和使用 ViewModel 的 Fragment 的代码。
@ExperimentalCoroutinesApi
@HiltViewModel
class ViewPrintOrderVM @Inject constructor(
private val repository: Repository,
private val application: Application,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// Code inside the ViewModel
}
在我的片段中,我得到的参考如下
@ExperimentalComposeUiApi
@ExperimentalCoroutinesApi
@AndroidEntryPoint
class ComposeFragmentPostPressDetails : Fragment() {
//Here we are scoping the ViewModel to the Navigation graph with graph-id instead of this fragment
private val viewModel: ManagePrintOrderVM by navGraphViewModels(R.id.print_order_flow)
//Rest of the Fragment code
}
现在,当我尝试通过在模拟器中启动应用程序,将其置于后台,然后使用 android 中的“终止应用程序”按钮终止进程来测试应用程序的进程终止时studio,它在重新创建时崩溃并出现以下错误
2022-03-19 19:06:44.633 7174-7174/com.sivakasi.papco.jobflow E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sivakasi.papco.jobflow, PID: 7174
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sivakasi.papco.jobflow/com.sivakasi.papco.jobflow.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.getViewModel(FragmentPaperDetails.kt:42)
at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.observeViewModel(FragmentPaperDetails.kt:97)
at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.onViewCreated(FragmentPaperDetails.kt:59)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1333)
at android.app.Activity.performStart(Activity.java:6992)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.InstantiationException: java.lang.Class<com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
但是,即使使用依赖项注入,ViewModel 的范围仅限于该片段而不是导航图的所有其他屏幕在进程重新创建时也能正常工作。
我做错了什么?我应该怎么做才能处理流程中的流程死亡?如何处理片段中的流程重新创建,其中 ViewModel 的范围是导航图而不是片段本身或 Activity?
by navGraphViewModels
对您的 Hilt 工厂一无所知 - 它只是使用默认工厂。它在其他情况下可能起作用的唯一原因是 确实 使用 Hilt 工厂的另一个片段首先创建了 ViewModel。
根据 the documentation,您必须使用 by hiltNavGraphViewModels()
才能使用限定在导航图范围内的 Hilt 注入 ViewModel。
// Add this to your dependencies
implementation 'androidx.hilt:hilt-navigation-fragment:1.0.0'
// Then use it in place of navGraphViewModels()
private val viewModel: ManagePrintOrderVM by hiltNavGraphViewModels(R.id.print_order_flow)
当我尝试在我的 Android 应用程序中处理进程死亡时,我注意到范围限定为导航图的 ViewModel 在从进程死亡中重新创建时崩溃了。下面是 ViewModel 和使用 ViewModel 的 Fragment 的代码。
@ExperimentalCoroutinesApi
@HiltViewModel
class ViewPrintOrderVM @Inject constructor(
private val repository: Repository,
private val application: Application,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// Code inside the ViewModel
}
在我的片段中,我得到的参考如下
@ExperimentalComposeUiApi
@ExperimentalCoroutinesApi
@AndroidEntryPoint
class ComposeFragmentPostPressDetails : Fragment() {
//Here we are scoping the ViewModel to the Navigation graph with graph-id instead of this fragment
private val viewModel: ManagePrintOrderVM by navGraphViewModels(R.id.print_order_flow)
//Rest of the Fragment code
}
现在,当我尝试通过在模拟器中启动应用程序,将其置于后台,然后使用 android 中的“终止应用程序”按钮终止进程来测试应用程序的进程终止时studio,它在重新创建时崩溃并出现以下错误
2022-03-19 19:06:44.633 7174-7174/com.sivakasi.papco.jobflow E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sivakasi.papco.jobflow, PID: 7174
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sivakasi.papco.jobflow/com.sivakasi.papco.jobflow.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.getViewModel(FragmentPaperDetails.kt:42)
at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.observeViewModel(FragmentPaperDetails.kt:97)
at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.onViewCreated(FragmentPaperDetails.kt:59)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1333)
at android.app.Activity.performStart(Activity.java:6992)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.InstantiationException: java.lang.Class<com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
但是,即使使用依赖项注入,ViewModel 的范围仅限于该片段而不是导航图的所有其他屏幕在进程重新创建时也能正常工作。
我做错了什么?我应该怎么做才能处理流程中的流程死亡?如何处理片段中的流程重新创建,其中 ViewModel 的范围是导航图而不是片段本身或 Activity?
by navGraphViewModels
对您的 Hilt 工厂一无所知 - 它只是使用默认工厂。它在其他情况下可能起作用的唯一原因是 确实 使用 Hilt 工厂的另一个片段首先创建了 ViewModel。
根据 the documentation,您必须使用 by hiltNavGraphViewModels()
才能使用限定在导航图范围内的 Hilt 注入 ViewModel。
// Add this to your dependencies
implementation 'androidx.hilt:hilt-navigation-fragment:1.0.0'
// Then use it in place of navGraphViewModels()
private val viewModel: ManagePrintOrderVM by hiltNavGraphViewModels(R.id.print_order_flow)