如何使用Hilt将Retrofit实例注入继承自普通Activity而非AppCompatActivity的类
问题原因
Hilt 官方的
@AndroidEntryPoint注解仅支持androidx.activity.ComponentActivity的子类(如 AppCompatActivity、FragmentActivity 等),原生android.app.Activity不在默认支持范围内,所以直接添加该注解会触发编译报错;而@ActivityScoped是作用域注解,不具备触发自动注入的能力,所以替换后会出现lateinit未初始化的运行时异常。
解决方案一:迁移为 AppCompatActivity(官方推荐,成本最低)
无需修改已写的 Hilt Module 代码,仅需要将 Activity 的父类从 Activity 替换为 AppCompatActivity,原有 @AndroidEntryPoint 注解即可正常生效:
@AndroidEntryPoint class MainActivity : AppCompatActivity() { ... @Inject lateinit var api: Api ... }
解决方案二:必须使用原生 Activity 时手动注入
如果业务强制要求继承原生 android.app.Activity,可以通过自定义 EntryPoint 手动完成依赖获取:
- 首先自定义注入入口接口,声明需要获取的依赖:
import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.android.EntryPointAccessors import dagger.hilt.components.SingletonComponent @EntryPoint @InstallIn(SingletonComponent::class) interface ApiEntryPoint { fun getApi(): Api }
- 在 Activity 的
onCreate生命周期中手动获取实例,不需要再加@AndroidEntryPoint或@Inject注解:
class MainActivity : Activity() { private lateinit var api: Api override fun onCreate(savedInstanceState: Bundle?) { // 从Application的Hilt容器中获取Api实例 val entryPoint = EntryPointAccessors.fromApplication( applicationContext, ApiEntryPoint::class.java ) api = entryPoint.getApi() super.onCreate(savedInstanceState) // 后续逻辑可正常使用api } }
注意事项
- 如果需要注入的是 Activity 作用域的依赖,只需要将 EntryPoint 的
@InstallIn目标改为ActivityComponent::class,同时使用EntryPointAccessors.fromActivity(this, ApiEntryPoint::class.java)来获取入口即可。 - 两种方案都不需要修改原有 Module 提供依赖的逻辑,可直接复用。
内容的提问来源于stack exchange,提问作者bqubique
相关产品推荐
相关产品推荐

