android - 使用 Hilt 将存储库注入 Android 中的服务
问题描述
我有一个带有 Hilt 依赖注入的 Android 项目。我已经定义MyApplication
和MyModule
如下。
@HiltAndroidApp
class MyApplication : Application()
@Module
@InstallIn(ApplicationComponent::class)
abstract class MyModule {
@Binds
@Singleton
abstract fun bindMyRepository(
myRepositoryImpl: MyRepositoryImpl
): MyRepository
}
MyRepositoryImpl
实现MyRepository
接口:
interface MyRepository {
fun doSomething(): String
}
class MyRepositoryImpl
@Inject
constructor(
) : MyRepository {
override fun doSomething() = ""
}
我现在可以将这个实现注入MyRepository
到 ViewModel 中:
class MyActivityViewModel
@ViewModelInject
constructor(
private val myRepository: MyRepository,
) : ViewModel() { }
这按预期工作。但是,如果我尝试将存储库注入到服务中,则会收到错误消息java.lang.Class<MyService> has no zero argument constructor
:
class MyService
@Inject
constructor(
private val myRepository: MyRepository,
): Service() { }
活动也会发生同样的错误:
class MyActivity
@Inject
constructor(
private val myRepository: MyRepository,
) : AppCompatActivity(R.layout.my_layout) { }
我在注射时做错了什么?
解决方案
从我们如何将依赖项注入 Android 类的文档中,我们可以了解到以下内容:
Hilt 可以为其他具有 @AndroidEntryPoint 注解的 Android 类提供依赖项。
Hilt 目前支持以下 Android 类:
Application
(通过使用@HiltAndroidApp
)Activity
Fragment
View
Service
BroadcastReceiver
因此,当您对这些 Android 类中的任何一个进行子类化时,您不会要求 Hilt 通过构造函数注入依赖项。相反,您使用 注释它@AndroidEntryPoint
,并要求 Hilt 通过使用注释属性来注入其依赖项@Inject
:
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
@Inject
lateinit var mAdapter: SomeAdapter
...
}
MyRepository
因此,在您的情况下MyActivity
,您应该像这样注入MyService
:
@AndroidEntryPoint
class MyService: Service() {
@Inject
lateinit var myRepository: MyRepository
...
}
@AndroidEntryPoint
class MyActivity: AppCompatActivity(R.layout.my_layout) {
@Inject
lateinit var myRepository: MyRepository
...
}
请记住:
Hilt 注入的字段不能是私有的
这就是 Hilt 支持的 Android 类。
如果您想知道 Hilt 不支持的类(例如:)怎么办ContentProvider
?!我建议从本教程中学习如何在codelab 上使用 @EntryPoint 注释(也不要忘记查看文档以了解如何在 Hilt 不支持的类中注入依赖项)。
推荐阅读
- amazon-web-services - 如何在 Elastic Beanstalk 环境变量中使用 AWS 参数存储变量?
- scala - Intellij Idea 2019.1.3 无法运行 ScalaTests
- reactjs - @material-ui/Icons 错误:对象作为 React 子项无效
- android - 如何在firebase实时数据库触发器上使用邮递员发送通知?
- javascript - 为什么 JavaScript 中 RegExp 的 matchAll 与其他方法如此不同?
- javascript - 如何使用随机选择的图像创建 Google 表单?
- mysql - MYSQL 删除所有行,但 select 上的相同查询仅返回 3 行
- django - 无法通过迁移将新模型添加到 Django Postgres DB
- python - 将新变量添加到 Python 中的数据集后的关键错误
- java - 对象可以具有未在类中定义的方法或变量吗?