Android 将类注入到视图中,以使用Hilt查看组件

Android 将类注入到视图中,以使用Hilt查看组件,android,dagger-2,dagger-hilt,Android,Dagger 2,Dagger Hilt,我有一个自定义WebView,可以添加到布局xml中: <my.company.ui.ExtendedWebView /> 如何使用Hilt将@Singelton类注入到上面的类中?财产注入?我应该如何注释该类?假设您的单例类目前看起来如下所示: class ExampleSingletonClass( //... some dependencies) { //.. some other stuff } 要使其成为单例,请将其更改为: @Singleton class

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

<my.company.ui.ExtendedWebView />

如何使用Hilt将
@Singelton
类注入到上面的类中?财产注入?我应该如何注释该类?

假设您的
单例类目前看起来如下所示:

class ExampleSingletonClass( //... some dependencies) {
     //.. some other stuff
}
要使其成为单例,请将其更改为:

@Singleton
class ExampleSingletonClass @Inject constructor( //... some dependencies) {
     //.. some other stuff
}
然后,要将其注入到您的
扩展WebView
中,请执行以下操作:

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
,但是您的
片段/活动需要
@AndroidEntryPoint

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

所以你认为你的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
因此,我了解到注释需要一路冒泡,从视图到(如果在片段中)片段,再到活动:

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

谢谢如果我这样做,我得到的
类型可能只包含一个@Inject构造函数
。我应该删除默认参数吗?@filur要么删除默认参数,要么用默认参数创建第二个构造函数,让它指向第一个构造函数。在第二个构造函数上也执行
@Inject
。你可以参考Gotcha。你能发布一个使用2构造函数方法的示例吗?@filur我很抱歉,但我发现这很不幸是不可能的(至少我是这样尝试的)。Kotlin无法区分两个构造函数,因为其中一个有默认值,而另一个没有。它表示
冲突重载
。我的解决方案:只要删除默认参数(如果可以的话),如果不能的话,你必须接受警告
类型可能只包含一个@injectconstructor
谢谢,我想在这种情况下删除它们不会有什么坏处,因为框架希望设置它们。是的,我得出了相同的结论。接受这个
@AndroidEntryPoint
class SuperAwesomeActivity : AppCompatActivity() {
...