Jetpack Compose中如何向ViewModel/ViewModelFactory传递id与Application
问题解决步骤
直接获取Application实例的实现
你可以通过Compose内置的LocalContext获取当前Android上下文,再取其applicationContext强转为Application实例即可,修改后RecallScreen代码如下:
@Composable fun RecallScreen( id:Long, onEnd:() -> Unit ){ // 从CompositionLocal中获取上下文并转换为Application val application = LocalContext.current.applicationContext as Application val recallViewModel = viewModel(factory = RecallViewModelFactory( id = id, application = application )) // 后续页面逻辑 }
如果需要避免强转崩溃,可以增加安全校验逻辑:
@Composable fun RecallScreen( id:Long, onEnd:() -> Unit ){ val context = LocalContext.current val application = remember(context) { context.applicationContext as? Application ?: throw IllegalArgumentException("当前上下文无法获取Application实例,请检查运行环境") } val recallViewModel = viewModel(factory = RecallViewModelFactory( id = id, application = application )) }
更简化的实现方案(无需自定义Factory)
因为你使用了Navigation Compose传递路由参数,可以借助SavedStateHandle直接在ViewModel中获取路由参数,不需要手动构造Factory传参,改造步骤如下:
- 修改ViewModel,直接从SavedStateHandle取id:
class RecallViewModel( application: Application, savedStateHandle: SavedStateHandle ):AndroidViewModel(application) { // 参数名和导航配置的"id"保持一致即可直接获取 private val id = savedStateHandle.get<Long>("id") ?: 0L // 原有ViewModel逻辑 }
- 页面中直接获取ViewModel,不需要自定义工厂:
@Composable fun RecallScreen( id:Long, onEnd:() -> Unit ){ val recallViewModel: RecallViewModel = viewModel() // 后续页面逻辑 }
该方案依赖lifecycle默认的ViewModel工厂,无需自己维护Factory逻辑,代码更简洁。
内容的提问来源于stack exchange,提问作者Omar Khaled
相关产品推荐
相关产品推荐

