android - 使用 Hilt 将存储库注入(inject) Android 中的服务

标签 android dependency-injection android-service dagger-hilt

我有一个带有 Hilt 依赖注入(inject)的 Android 项目。我已经定义了MyApplicationMyModule如下。

@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() = ""
}
我现在可以注入(inject) MyRepository 的这个实现进入 View 模型:
class MyActivityViewModel
@ViewModelInject
constructor(
    private val myRepository: MyRepository,
) : ViewModel() { }
这按预期工作。但是,如果我尝试将存储库注入(inject)服务,则会收到错误 java.lang.Class<MyService> has no zero argument constructor :
class MyService
@Inject
constructor(
    private val myRepository: MyRepository,
): Service() { }
Activity 也会发生同样的错误:
class MyActivity
@Inject
constructor(
    private val myRepository: MyRepository,
) : AppCompatActivity(R.layout.my_layout) { }
我在注入(inject)时做错了什么?

最佳答案

来自关于我们如何 Inject dependencies into Android classes 的文档,我们可以学习以下内容:

Hilt can provide dependencies to other Android classes that have the @AndroidEntryPoint annotation.

Hilt currently supports the following Android classes:

  • Application (by using @HiltAndroidApp)
  • ViewModel (by using @HiltViewModel)
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver

因此,当您对这些 Android 类中的任何一个进行子类化时,您不会要求 Hilt 通过构造函数注入(inject)依赖项。相反,您使用 @AndroidEntryPoint 对其进行注释。 ,并要求 Hilt 通过使用 @Inject 注释属性来注入(inject)其依赖项:
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() { 

    @Inject
    lateinit var mAdapter: SomeAdapter 

    ...

}
因此,在您的情况下,您应该注入(inject) MyRepositoryMyActivityMyService像这样:
@AndroidEntryPoint
class MyService: Service() {

    @Inject
    lateinit var myRepository: MyRepository
   
    ...

}

@AndroidEntryPoint
class MyActivity: AppCompatActivity(R.layout.my_layout) { 

    @Inject
    lateinit var myRepository: MyRepository

    ...

}
请记住:

Fields injected by Hilt cannot be private


这就是 Hilt 支持的 Android 类。
如果您想知道 Hilt 不支持的类(例如:ContentProvider)怎么办?!我建议从本教程中学习如何 @EntryPoint annotation on codelab (也不要忘记查看文档以了解如何使用 Inject dependencies in classes not supported by Hilt )。

关于android - 使用 Hilt 将存储库注入(inject) Android 中的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63766576/

相关文章:

android - 如何在 Bundle 中发送自定义对象的 ArrayList

Android 重复闹钟调用服务

android - 将数据放入 Android 4.4 错误位置中的 JSON 对象

java - 读取心电图数据的开源java库?

java - 基于位置的自动移动静音 Action

asp.net-web-api - 字符串类型不能构造

javascript - 在 Aurelia 中注入(inject)多个使用 fetch HttpClient 的类

android lollipop - fragment 的 setentertransition() 在退出时无法正常工作

java - 安卓未捕获异常

java - Spring 将 Clock 作为构造函数参数注入(inject)时出现问题