使用 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
    }

    //...
}