使用 Hilt 提供 Activity 个实例
Provide Activity instance with Hilt
如何翻译这样的内容:
@Module
abstract class BaseActivityModule<A : AppCompatActivity> {
@Binds
abstract fun provideActivity(activity: A): AppCompatActivity
companion object {
@Provides
@ActivityContext
fun provideContext(activity: AppCompatActivity): Context = activity
}
}
@Module
abstract class SomeActivityModule : BaseActivityModule<SomeActivity>()
所以后面可以这样使用:
@ActivityScope
class UtilsClass @Inject constructor(
private val activity: AppCompatActivity,
...
){...}
我已经将一个 playground 项目从 dagger
迁移到 hilt
并且非常顺利,但我偶然发现了这个用例。我已经更改了代码,因此不再需要该实例,但好奇心依然存在。
现在我们甚至不需要这种设置了吗:
@ActivityScope
@ContributesAndroidInjector(modules = [SomeActivityModule::class])
abstract fun someActivity(): SomeActivity
是的,我们不需要这种设置。我们只需为我们的活动提供 @AndroidEntryPoint,Hilt 将自行处理依赖项注入。同样使用 Hilt,无需编写 Factory 和 InjectorComponents。
我还没有尝试过这段代码,如果它不起作用请 CMiMW,
根据文档 here,您可以为应用程序上下文和 activity 上下文使用预定义的限定符。
您的代码可能如下所示
@ActivityScoped
class UtilsClass @Inject constructor(
@ActivityContext private val activity: Context,
...
){
...
val myActivity = if(context is MyActivity) context as MyActivity else throw ...... // check if its provided context was desired activity
...
}
是的,您可以将 @ActivityContext
转换为您的 activity,请继续阅读以获得更多说明。
@ActivityContext
可用于限定需要绑定的范围activity 上下文。
但类似于匕首范围方案,您只能在 class 范围内 @ActivityScoped
,即,如果您在 class 中尝试 @ActivityContext
并将其范围扩大到任何其他范围比 @ActivityScoped
,你将面临编译时错误
@dagger.hilt.android.qualifiers.ActivityContext
android.content.Context cannot be provided without an
@Provides-annotated method
此外,每次创建新的 activity 时都会实例化新的绑定对象。
参考https://developer.android.com/training/dependency-injection/hilt-android#component-scopes
只是 cast/get activity 来自上下文。但是也可以根据docs
指定class
tailrec fun Context?.activity(): Activity? = this as? Activity
?: (this as? ContextWrapper)?.baseContext?.activity()
class MyClass @Inject constructor(@ActivityContext context: Context) {
init {
val activity = context.activity() as Activity
}
//...
}
如何翻译这样的内容:
@Module
abstract class BaseActivityModule<A : AppCompatActivity> {
@Binds
abstract fun provideActivity(activity: A): AppCompatActivity
companion object {
@Provides
@ActivityContext
fun provideContext(activity: AppCompatActivity): Context = activity
}
}
@Module
abstract class SomeActivityModule : BaseActivityModule<SomeActivity>()
所以后面可以这样使用:
@ActivityScope
class UtilsClass @Inject constructor(
private val activity: AppCompatActivity,
...
){...}
我已经将一个 playground 项目从 dagger
迁移到 hilt
并且非常顺利,但我偶然发现了这个用例。我已经更改了代码,因此不再需要该实例,但好奇心依然存在。
现在我们甚至不需要这种设置了吗:
@ActivityScope
@ContributesAndroidInjector(modules = [SomeActivityModule::class])
abstract fun someActivity(): SomeActivity
是的,我们不需要这种设置。我们只需为我们的活动提供 @AndroidEntryPoint,Hilt 将自行处理依赖项注入。同样使用 Hilt,无需编写 Factory 和 InjectorComponents。
我还没有尝试过这段代码,如果它不起作用请 CMiMW,
根据文档 here,您可以为应用程序上下文和 activity 上下文使用预定义的限定符。
您的代码可能如下所示
@ActivityScoped
class UtilsClass @Inject constructor(
@ActivityContext private val activity: Context,
...
){
...
val myActivity = if(context is MyActivity) context as MyActivity else throw ...... // check if its provided context was desired activity
...
}
是的,您可以将 @ActivityContext
转换为您的 activity,请继续阅读以获得更多说明。@ActivityContext
可用于限定需要绑定的范围activity 上下文。
但类似于匕首范围方案,您只能在 class 范围内 @ActivityScoped
,即,如果您在 class 中尝试 @ActivityContext
并将其范围扩大到任何其他范围比 @ActivityScoped
,你将面临编译时错误
@dagger.hilt.android.qualifiers.ActivityContext android.content.Context cannot be provided without an @Provides-annotated method
此外,每次创建新的 activity 时都会实例化新的绑定对象。
参考https://developer.android.com/training/dependency-injection/hilt-android#component-scopes
只是 cast/get activity 来自上下文。但是也可以根据docs
指定classtailrec fun Context?.activity(): Activity? = this as? Activity
?: (this as? ContextWrapper)?.baseContext?.activity()
class MyClass @Inject constructor(@ActivityContext context: Context) {
init {
val activity = context.activity() as Activity
}
//...
}