如何实现仅单个flavor使用自定义Dagger模块其余flavor沿用默认实现
解决方案
Android Gradle 插件构建多 flavor 应用时,默认会将
main源码集和对应 flavor 的源码集合并编译,如果两个源码集中存在全限定名完全相同的类,就会触发重声明冲突。
方案1:源码集排除(侵入性最低,无需修改业务代码)
这是最适配你需求的方案,只需要修改构建配置,不需要调整Dagger相关代码,其他flavor完全无感知。
操作步骤:
- 保持你现有结构:默认 Dagger Module 放在
main目录下,需要替换的目标 flavor 目录下存放同名、同全限定名的自定义 Module - 在模块级构建配置中添加规则,仅为需要替换的flavor排除
main目录下的默认Module:
Kotlin DSL(build.gradle.kts)示例:
Groovy(android { productFlavors { // 假设你需要替换的flavor名为custom create("custom") { dimension = "app" // 你的原有flavor配置 } // 其余4个flavor正常配置即可 } sourceSets { // 仅为custom flavor排除main中的默认Module named("custom") { java { // 替换为你默认Module的实际路径,Kotlin代码就把java改成kotlin exclude("com/your/package/YourTargetModule.kt") } } } }build.gradle)示例:android { productFlavors { custom { dimension 'app' // 你的原有flavor配置 } } sourceSets { custom { java { exclude 'com/your/package/YourTargetModule.java' } } } }
原理:构建custom flavor时,Gradle会忽略main目录下的同名Module,优先使用flavor目录下的实现;其余flavor构建时不会触发排除逻辑,直接使用main下的默认实现,全程不需要修改Dagger组件的module依赖配置。
方案2:动态传入Module(无需修改构建配置)
如果你不想修改Gradle配置,可以用Dagger组件的Factory/Builder动态传入对应Module,不需要让Module同名:
- 在
main目录下存放默认实现的Module,命名为DefaultFeatureModule - 仅在目标flavor的目录下存放自定义实现的Module,命名为
CustomFeatureModule,不要和默认Module重名 - 给你的AppComponent添加工厂方法,将FeatureModule作为参数传入:
@Singleton @Component(modules = [/* 其他固定Module */]) interface AppComponent { @Component.Factory interface Factory { fun create( @BindsInstance context: Context, featureModule: FeatureModule // 这里也可以传入两个Module共同实现的接口/父类 ): AppComponent } } - 在Application初始化时根据flavor判断传入的Module实例:
class MyApp : Application() { override fun onCreate() { super.onCreate() val featureModule = if (BuildConfig.FLAVOR == "custom") { CustomFeatureModule() } else { DefaultFeatureModule() } val component = DaggerAppComponent.factory().create(this, featureModule) // 其余初始化逻辑 } }
内容的提问来源于stack exchange,提问作者user1116714
相关产品推荐
相关产品推荐

