进程死亡时导航图作用域 ViewModel

Sun*_*vel 2 java android viewmodel

当我尝试在 Android 应用程序中处理进程死亡时,我注意到范围为导航图的 ViewModel 在从进程死亡中重新创建时崩溃了。下面是 ViewModel 和使用 ViewModel 的 Fragment 的代码。

\n
@ExperimentalCoroutinesApi\n@HiltViewModel\nclass ViewPrintOrderVM @Inject constructor(\nprivate val repository: Repository,\nprivate val application: Application,\nprivate val savedStateHandle: SavedStateHandle\n) : ViewModel() {\n\n     // Code inside the ViewModel\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在我的片段中,我得到的参考如下

\n
@ExperimentalComposeUiApi\n@ExperimentalCoroutinesApi\n@AndroidEntryPoint\nclass ComposeFragmentPostPressDetails : Fragment() {\n\n        //Here we are scoping the ViewModel to the Navigation graph with graph-id instead of this fragment\n        private val viewModel: ManagePrintOrderVM by navGraphViewModels(R.id.print_order_flow)\n\n       //Rest of the Fragment code\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在,当我尝试通过在模拟器中启动应用程序,将其放在后台,然后使用 android studio 中的“终止应用程序”按钮终止进程来测试应用程序的进程死亡时,它在使用以下命令重新创建时崩溃错误

\n
2022-03-19 19:06:44.633 7174-7174/com.sivakasi.papco.jobflow E/AndroidRuntime: FATAL EXCEPTION: main\n    Process: com.sivakasi.papco.jobflow, PID: 7174\n    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\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)\n        at android.app.ActivityThread.-wrap11(Unknown Source:0)\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)\n        at android.os.Handler.dispatchMessage(Handler.java:105)\n        at android.os.Looper.loop(Looper.java:164)\n        at android.app.ActivityThread.main(ActivityThread.java:6541)\n        at java.lang.reflect.Method.invoke(Native Method)\n        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\n     Caused by: java.lang.RuntimeException: Cannot create an instance of class com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM\n        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)\n        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)\n        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)\n        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)\n        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)\n        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)\n        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)\n        at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.getViewModel(FragmentPaperDetails.kt:42)\n        at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.observeViewModel(FragmentPaperDetails.kt:97)\n        at com.sivakasi.papco.jobflow.screens.manageprintorder.FragmentPaperDetails.onViewCreated(FragmentPaperDetails.kt:59)\n        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987)\n        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)\n        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)\n        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)\n        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)\n        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)\n        at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)\n        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)\n        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)\n        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)\n        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)\n        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)\n        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)\n        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072)\n        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)\n        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502)\n        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)\n        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1333)\n        at android.app.Activity.performStart(Activity.java:6992)\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)\xc2\xa0\n        at android.app.ActivityThread.-wrap11(Unknown Source:0)\xc2\xa0\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)\xc2\xa0\n        at android.os.Handler.dispatchMessage(Handler.java:105)\xc2\xa0\n        at android.os.Looper.loop(Looper.java:164)\xc2\xa0\n        at android.app.ActivityThread.main(ActivityThread.java:6541)\xc2\xa0\n        at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\xc2\xa0\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\xc2\xa0\n     Caused by: java.lang.InstantiationException: java.lang.Class<com.sivakasi.papco.jobflow.screens.manageprintorder.ManagePrintOrderVM> has no zero argument constructor\n        at java.lang.Class.newInstance(Native Method)\n
Run Code Online (Sandbox Code Playgroud)\n

然而,ViewModel 的范围仅限于该 Fragment 而不是导航图的所有其他屏幕,即使使用依赖项注入,也可以在流程重新创建时正常工作。

\n

我究竟做错了什么?我应该如何处理流程中的进程死亡?如何处理片段中的流程重新创建,其中 ViewModel 的范围仅限于导航图而不是片段本身或活动?

\n

ian*_*ake 5

by navGraphViewModels对你的 Hilt 工厂一无所知 - 它只是使用默认工厂。它在其他情况下可能起作用的唯一原因是因为另一个使用 Hilt 工厂的片段首先创建了 ViewModel。

根据文档,您必须使用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)
Run Code Online (Sandbox Code Playgroud)