You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose结合Anvil:Composable中ViewModel注入优化方案咨询

利用Anvil在Compose Navigation中优雅注入ViewModel

核心思路

借助Anvil的@ContributesViewModel注解自动生成ViewModel Factory,无需手动创建和传递Factory;结合Anvil的依赖注入上下文,在Composable中直接获取ViewModel,彻底避免从Activity层层传递Factory的冗余逻辑。


步骤1:给ViewModel添加Anvil注解

用@ContributesViewModel标记ViewModel,并在构造函数中注入所需依赖,Anvil会自动生成对应的Factory并将其绑定到依赖体系中。

@ContributesViewModel(AppScope::class) // 替换为你的全局Scope(如自定义的AppScope)
class ProfileViewModel @Inject constructor(
    private val userRepository: UserRepository // 示例依赖,根据实际业务替换
) : ViewModel() {
    // 你的ViewModel业务逻辑实现
}

步骤2:在Compose树中注入Anvil上下文

在MainActivity中初始化Anvil根Component,通过AnvilInject组合函数将注入上下文传递给整个Compose树,确保所有子Composable都能访问到依赖注入体系:

class MainActivity : ComponentActivity() {
    private val appComponent = DaggerAppComponent.create() // 初始化你的根Component

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AnvilInject(appComponent) {
                // 放置你的NavHost或根Composable
                MyAppNavHost()
            }
        }
    }
}

步骤3:封装Compose扩展函数(可选但推荐)

封装通用的Compose扩展函数,简化ViewModel的获取逻辑,避免重复编写ViewModelProvider的初始化代码:

@Composable
inline fun <reified T : ViewModel> anvilViewModel(): T {
    val viewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
        "当前上下文找不到ViewModelStoreOwner"
    }
    val factory = get<ViewModelProvider.Factory>() // 从Anvil注入上下文获取Factory
    return ViewModelProvider(viewModelStoreOwner, factory)[T::class.java]
}

步骤4:优化Navigation Destination代码

现在无需在ProfileDestination中传递Factory参数,直接在Composable中使用封装的扩展函数获取ViewModel即可:

fun NavGraphBuilder.ProfileDestination(route: String) {
    composable(route) {
        val profileViewModel: ProfileViewModel = anvilViewModel()
        ProfileScreen(profileViewModel = profileViewModel)
    }
}

额外说明

  • Anvil的@ContributesViewModel会自动将生成的ViewModel Factory绑定到ViewModelProvider.Factory,根Component会自动聚合所有这类Factory,无需手动维护Factory集合
  • 这种方案彻底解除了MainActivity与ViewModel Factory的耦合,依赖注入逻辑完全由Anvil管理,符合单一职责原则
  • 若不想封装扩展函数,也可直接在Composable中调用ViewModelProvider,但扩展函数能大幅简化代码量

内容的提问来源于stack exchange,提问作者Ashraf Mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:53:19