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

Android多模块+Hilt依赖注入冲突问题解决方案求助

Android多模块Hilt运行时动态选择依赖解决方案

方案1:接口抽象+Map绑定工厂模式(推荐纯运行时动态选择场景)

核心思路是用接口解耦Common模块与具体实现,借助Hilt的@IntoMap绑定所有实现类,再通过工厂类根据运行时条件动态获取实例,完全避免在Common模块硬编码限定符。

步骤拆解:

  1. Common模块定义抽象接口
    把原来直接依赖的A、B类型替换为抽象接口,让Library A/B各自实现:

    // Common模块
    interface CoreFeature {
        fun executeBusinessLogic()
    }
    
  2. Library A/B实现接口并绑定到Map
    每个Library用自定义限定符标记自身实现,同时通过@IntoMap将实例绑定到String键的Map中(键名保证唯一即可):

    // Library A模块
    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    private annotation class LibraryA
    
    class LibraryAFeature @Inject constructor() : CoreFeature {
        override fun executeBusinessLogic() {
            // Library A的具体业务逻辑
        }
    }
    
    @Module
    @InstallIn(SingletonComponent::class)
    object LibraryAModule {
        @LibraryA
        @Provides
        @IntoMap
        @StringKey("feature_a")
        fun provideLibraryAFeature(): CoreFeature = LibraryAFeature()
    }
    

    Library B实现对称修改即可:

    // Library B模块
    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    private annotation class LibraryB
    
    class LibraryBFeature @Inject constructor() : CoreFeature {
        override fun executeBusinessLogic() {
            // Library B的具体业务逻辑
        }
    }
    
    @Module
    @InstallIn(SingletonComponent::class)
    object LibraryBModule {
        @LibraryB
        @Provides
        @IntoMap
        @StringKey("feature_b")
        fun provideLibraryBFeature(): CoreFeature = LibraryBFeature()
    }
    
  3. Common模块实现动态选择工厂
    注入Hilt自动生成的Map<String, CoreFeature>,根据运行时条件返回对应实例:

    // Common模块
    class FeatureSelector @Inject constructor(
        private val featureMap: Map<String, @JvmSuppressWildcards CoreFeature>
    ) {
        fun getSelectedFeature(useLibraryA: Boolean): CoreFeature {
            val key = if (useLibraryA) "feature_a" else "feature_b"
            return featureMap[key] ?: throw IllegalStateException("No feature implementation found for key: $key")
        }
    }
    
  4. Common模块使用动态依赖
    注入FeatureSelector,在业务逻辑中根据条件获取实例:

    // Common模块业务类
    class CommonBusinessLogic @Inject constructor(
        private val featureSelector: FeatureSelector
    ) {
        fun doWork(useLibraryA: Boolean) {
            val feature = featureSelector.getSelectedFeature(useLibraryA)
            feature.executeBusinessLogic()
        }
    }
    

方案2:Gradle变体控制(适合编译时确定依赖的场景)

如果选择逻辑在编译阶段就能确定(比如不同产品flavor、环境),可以直接通过Gradle变体控制只引入其中一个Library,从根源避免依赖冲突:

配置示例:

在App模块的build.gradle中定义产品flavor,为不同flavor绑定对应Library:

// App模块build.gradle
android {
    flavorDimensions "feature"
    productFlavors {
        useLibraryA {
            dimension "feature"
        }
        useLibraryB {
            dimension "feature"
        }
    }
}

dependencies {
    useLibraryAImplementation project(':libraryA')
    useLibraryBImplementation project(':libraryB')
    implementation project(':common')
}

编译时选择对应flavor即可,Common模块无需修改,Hilt编译阶段只会看到一个实现类,不会报冲突。

方案3:动态特性模块+EntryPoint(适合按需加载场景)

如果Library A/B是可选的、需要按需加载的功能,可将它们做成Android动态特性模块,通过Hilt的@EntryPoint在运行时加载模块后获取实例:

关键步骤:

  1. 将Library A/B配置为动态特性模块(build.gradle中添加apply plugin: 'com.android.dynamic-feature')
  2. Common模块定义EntryPoint接口:
    // Common模块
    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface FeatureEntryPoint {
        fun getCoreFeature(): CoreFeature
    }
    
  3. 运行时加载模块后获取实例:
    // 加载模块并使用的逻辑
    fun loadFeatureAndUse(useLibraryA: Boolean) {
        val moduleName = if (useLibraryA) "libraryA" else "libraryB"
        SplitInstallManager.create(this).startInstall(
            SplitInstallRequest.newBuilder().addModule(moduleName).build()
        ).addOnSuccessListener {
            val entryPoint = EntryPointAccessors.fromApplication(
                applicationContext,
                FeatureEntryPoint::class.java
            )
            val feature = entryPoint.getCoreFeature()
            feature.executeBusinessLogic()
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:10:30