如何在Android library(aar)中使用Hilt且无需客户端做任何适配改动?
Manifest合并冲突解决方案
你遇到的Manifest冲突核心原因是Library模块不应该声明自定义Application类,客户端的Application实现完全由客户端自身控制,解决方案如下:
- 删除library模块
AndroidManifest.xml中<application>标签下的android:name属性配置 - 移除你之前定义的带
@HiltAndroidApp注解的Sdk自定义Application类
之前使用
tools:replace="android:name"的方案属于破坏性操作,会直接覆盖客户端的Application实现,导致客户端自身的初始化逻辑完全失效,绝对不能用于生产环境。
库内部隔离使用Hilt方案
Hilt提供了@EntryPoint组件专门适配库开发场景,可以实现Hilt注入逻辑完全在库内部闭环,客户端无需做任何Hilt相关适配,同时兼容你提到的三种客户端场景:
1. 定义库内部Hilt入口与组件
在库内部自行定义Hilt组件和入口点,和客户端的DI环境完全隔离:
// 1. 定义EntryPoint,暴露库内部需要的依赖 @EntryPoint @InstallIn(SingletonComponent::class) interface SdkEntryPoint { // 按业务需要声明需要获取的依赖 fun provideApiService(): ApiService fun provideUserManager(): UserManager } // 2. 定义库内部独立的Hilt组件 @Singleton @Component(modules = [ SdkNetworkModule::class, SdkRepositoryModule::class // 你自定义的所有Hilt Module都在这里配置 ]) interface SdkComponent { fun getEntryPoint(): SdkEntryPoint @Component.Builder interface Builder { @BindsInstance fun bindApplication(application: Application): Builder fun build(): SdkComponent } }
2. 库内部初始化Hilt容器
在库内部自行管理Hilt组件的初始化,不需要客户端参与:
// 库内部单例持有Hilt组件 object SdkInjectHolder { private lateinit var entryPoint: SdkEntryPoint // 内部初始化方法,不需要对外暴露 fun init(application: Application) { if (::entryPoint.isInitialized) return entryPoint = DaggerSdkComponent.builder() .bindApplication(application) .build() .getEntryPoint() } // 内部方法获取依赖 fun <T> getDependency(provider: (SdkEntryPoint) -> T): T { return provider(entryPoint) } }
3. 库内部业务使用注入
库内部的Activity、工具类等场景直接从自己的Hilt容器取依赖即可,不需要加@AndroidEntryPoint注解:
class SdkBusinessActivity : AppCompatActivity() { // 直接获取依赖,不需要客户端参与注入 private val apiService = SdkInjectHolder.getDependency { it.provideApiService() } private val userManager = SdkInjectHolder.getDependency { it.provideUserManager() } override fun onCreate(savedInstanceState: Bundle?) { // 首次启动页面时懒初始化,不需要客户端主动调用初始化接口 if (!SdkInjectHolder::entryPoint.isInitialized) { SdkInjectHolder.init(application) } super.onCreate(savedInstanceState) // 业务逻辑正常实现 } }
客户端场景兼容说明
- 客户端未自定义Application:无任何影响,库会自动使用系统默认的Application实例完成内部初始化
- 客户端已使用Hilt:完全无冲突,库的Hilt容器和客户端的Hilt容器是完全独立的两个实例,互不干扰
- 客户端使用Dagger或其他DI框架:无耦合,库的注入逻辑完全在内部闭环,和客户端的DI框架没有任何交互
内容的提问来源于stack exchange,提问作者c-an
相关产品推荐
相关产品推荐

