如何基于BuildConfig条件添加注解解决Hilt多应用入口冲突
核心结论
直接通过BuildConfig的值条件性添加@HiltAndroidApp注解不可行——Hilt的注解处理器会在编译阶段扫描所有带该注解的类,只要存在多个就会触发Cannot process multiple app roots in the same compilation unit错误,且注解参数不支持运行时动态判断。
可行解决方案:变体专属源集隔离
最稳妥的方式是利用Android的变体专属源集,为不同构建变体提供独立的Application类,确保每个变体编译时仅存在一个带@HiltAndroidApp的入口类。
步骤1:定义公共基类(主源集)
在src/main/java/[你的包名]下创建不带Hilt注解的基类Application,统一所有变体共享的逻辑:
open class BaseApplication : Application() { // 所有变体通用的初始化逻辑、工具方法等 }
步骤2:为普通变体创建Hilt入口类
在普通变体的源集目录(比如src/normalDebug/java/[你的包名]、src/normalRelease/java/[你的包名],假设普通变体名为normal)下,创建带Hilt注解的Application类:
@HiltAndroidApp class MainApplication : BaseApplication() { }
步骤3:为AirWatch变体创建适配的Hilt入口类
在AirWatch变体的源集目录(比如src/awDebug/java/[你的包名]、src/awRelease/java/[你的包名],假设AW变体名为aw)下,创建适配AirWatch的Hilt入口类:
@HiltAndroidApp class MainAWApplication : BaseApplication(), AWSDKApplication by AWSDKApplicationDelegate() { }
步骤4:配置Manifest自动替换Application类
在主源集的AndroidManifest.xml中,用占位符指定Application类,由Gradle根据变体自动替换:
<application android:name="${applicationClass}" <!-- 其他原有配置 --> >
然后在模块的build.gradle.kts中,为不同变体配置对应占位符值:
android { productFlavors { create("normal") { manifestPlaceholders["applicationClass"] = "[你的包名].MainApplication" } create("aw") { manifestPlaceholders["applicationClass"] = "[你的包名].MainAWApplication" } } }
方案优势
每个构建变体编译时,Gradle只会合并当前变体的源集代码,最终编译单元中只会存在一个带@HiltAndroidApp的Application类,从根源上规避了Hilt的多入口冲突问题,同时保持了不同变体代码的独立性。
内容的提问来源于stack exchange,提问作者frodo2975

