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

Navigation Compose中动态功能模块与Jetpack Compose、Dagger集成方案咨询

Jetpack Compose + Dagger + 按需动态功能模块实现思路
  • 定义跨模块依赖接口
    宿主模块中创建CoreDependencies接口,暴露动态模块需要的核心依赖(如Context、全局Repository等),同时定义DynamicFeatureComponentProvider接口,规定动态模块需实现的组件提供方法:

    interface CoreDependencies {
        fun appContext(): Context
        fun userRepository(): UserRepository
    }
    
    interface DynamicFeatureComponentProvider {
        fun createComponent(dependencies: CoreDependencies): DynamicFeatureComponent
    }
    
  • 动态模块的Dagger配置
    在按需加载的动态模块中,创建Dagger Subcomponent,依赖宿主的CoreDependencies,并实现DynamicFeatureComponentProvider:

    @Subcomponent(modules = [DynamicFeatureModule::class])
    interface DynamicFeatureComponent {
        fun inject(featureScreen: DynamicFeatureScreen)
        // 暴露Compose需要的依赖,比如ViewModel Factory
        fun viewModelFactory(): ViewModelProvider.Factory
    }
    
    class DynamicFeatureComponentProviderImpl : DynamicFeatureComponentProvider {
        override fun createComponent(dependencies: CoreDependencies): DynamicFeatureComponent {
            return DaggerDynamicFeatureComponent.builder()
                .coreDependencies(dependencies)
                .build()
        }
    }
    

    同时在动态模块的AndroidManifest.xml中注册这个Provider,方便宿主通过组件名获取:

    <meta-data
        android:name="com.yourpackage.DynamicFeatureComponentProvider"
        android:value="com.yourpackage.dynamic.DynamicFeatureComponentProviderImpl" />
    
  • 宿主加载动态模块并初始化组件
    完成模块加载后,通过反射或读取Manifest元数据获取DynamicFeatureComponentProviderImpl实例,传入宿主的CoreDependencies实现(比如AppComponent实现该接口),初始化动态模块的Component:

    // 模块加载完成后
    val providerClassName = // 从Manifest中读取meta-data的值
    val providerClass = Class.forName(providerClassName)
    val provider = providerClass.newInstance() as DynamicFeatureComponentProvider
    val dynamicComponent = provider.createComponent(appComponent as CoreDependencies)
    // 将Component保存到全局Holder,方便后续Compose使用
    DynamicComponentHolder.setComponent(dynamicComponent)
    
  • Compose中接入依赖
    在动态模块的Composable界面中,通过CompositionLocal获取依赖:

    val LocalDynamicComponent = staticCompositionLocalOf<DynamicFeatureComponent> {
        error("Dynamic Component not initialized")
    }
    
    @Composable
    fun DynamicFeatureScreen() {
        val component = LocalDynamicComponent.current
        val viewModel = viewModel(factory = component.viewModelFactory())
        // 渲染Compose界面
    }
    

    宿主启动该Composable时,用CompositionLocalProvider注入Component:

    @Composable
    fun HostScreen() {
        DynamicComponentHolder.getComponent()?.let { component ->
            CompositionLocalProvider(LocalDynamicComponent provides component) {
                DynamicFeatureScreen()
            }
        } ?: run {
            // 显示模块加载中或错误状态
        }
    }
    
  • 关键注意事项

    • ProGuard配置:保留DynamicFeatureComponentProvider接口和实现类,避免被混淆导致反射失败
    • 异步处理:模块加载是异步操作,需确保在加载完成后再初始化组件和跳转界面
    • Compose预览:动态模块的Compose预览需依赖宿主的CoreDependencies模拟实现,可单独创建预览用的依赖类

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:50:24