注入 class 以使用 Hilt 查看组件

Inject class in to view component with Hilt

我有一个添加到布局中的自定义 WebView xml:

<my.company.ui.ExtendedWebView />

它扩展了原生 WebView:

class ExtendedWebView @JvmOverloads constructor(context: Context, 
    attrs: AttributeSet? = null,  defStyle: Int = 0) 
    : WebView(context, attrs, defStyle) {
// ...
}

如何使用 Hilt 将 @Singelton class 注入到上面的 class 中? 属性注射?我应该如何注释 class?

假设您的 singleton class 目前看起来像这样:

class ExampleSingletonClass( //... some dependencies) {
     //.. some other stuff
}

要使其成为单例,请将其更改为:

@Singleton
class ExampleSingletonClass @Inject constructor( //... some dependencies) {
     //.. some other stuff
}

然后,要将其注入您的 ExtendedWebView,请执行以下操作:

class ExtendedWebView @JvmOverloads @Inject constructor(
    context: Context, 
    attrs: AttributeSet? = null,  
    defStyle: Int = 0,
    private val exampleSingleton: ExampleSingletonClass // your singleton, doesn't need to be private.
   ) : WebView(context, attrs, defStyle) {
// ...
}

这里你不需要 @AndroidEntryPoint,但是你的 Fragment / Activity 需要 @AndroidEntryPoint

我发现 @AndroidEntryPoint 注释需要在视图、片段(如果在片段中)和 Activity 上。因为注释。

所以请考虑您的 DI 设置如下:

/* CONTENTS OF com.org.app.di/dependencyModule.kt */
@Module
@InstallIn(ViewComponent::class)
object DependencyModule {
    @Provides
    fun provideDependency(@ApplicationContext context: Context): DependencyType
            = DependencyInstance(context)
}

我的应用程序设置正确:

@HiltAndroidApp
class SuperAwesomeApplication : Application()
/* Remember to reference this is the manifest file, under the name attricbute! */

现在,如果我有一个带有注入依赖项的视图:

@AndroidEntryPoint
class SuperAwesomeView(context: Context, attrs: AttributeSet) : View(context, attrs) {
    @Inject
    lateinit var dependency: DependencyType
    ...

我会得到错误:

...
Caused by: java.lang.IllegalStateException: class com.app.org.ui.view.SuperAwesomeView, Hilt view must be attached to an @AndroidEntryPoint Fragment or Activity.
...

所以我将 @AndroidEntryPoint 注释添加到包含视图的片段中:

@AndroidEntryPoint
class SuperAwesomeFragment : Fragment() {
...

然后我们遇到下一个错误:

 Caused by: java.lang.IllegalStateException: Hilt Fragments must be attached to an @AndroidEntryPoint Activity. Found: class com.org.ui.SuperAwesomeActivity

所以我了解到注释需要一直向上冒泡,从视图到(如果在片段中)片段,再到 Activity:

@AndroidEntryPoint
class SuperAwesomeActivity : AppCompatActivity() {
...