Dagger 2 在 Kotlin 对象中注入上下文
Dagger 2 Inject Context in Kotlin Object
我正在尝试使用 Dagger 2 注入 Context
。
AppComponent.kt:
@Singleton
@Component(
modules = [
AppModule::class
]
)
interface AppComponent {
fun context(): Context
}
AppModule.kt:
@Module
class AppModule(private val application: Application) {
@Provides
@Singleton
fun providesApplicationContext(): Context = application
}
MainApp.kt:
class MainApp : Application() {
lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
appComponent = initDagger()
}
private fun initDagger() = DaggerAppComponent.builder()
.appModule(AppModule(this))
.build()
}
Manager.kt: (Class 我要注入的地方 Context
)
object Manager {
@Inject
lateinit var context: Context
}
但是,我收到以下错误:
error: Dagger does not support injection into static fields
public static android.content.Context context;
^
这是因为我使用的是 object
(单例)吗?
如果您对问题有任何疑问,请在下面发表评论。谢谢。
Is this because I am using an object
(Singleton)?
是的,object
s 的属性是 Java 的静态字段。您的 Manager
class 将反编译为类似于以下内容的内容:
public final class Manager {
@Inject
@NotNull
public static Context context;
public static final Manager INSTANCE;
static {
INSTANCE = new Manager();
}
private Manager() {
}
@NotNull
public final Context getContext() {
return context;
}
public final setContext(Context var1) {
context = var1;
}
}
而 Dagger 2 只是 does not support injection into static fields
。然而,即使 Dagger 让你这样做,依赖性也不会得到满足。那是因为 Dagger 将无法注入到一个对象中,除非被明确告知这样做(就像你在注入到活动中时所做的那样)或自己创建对象。显然后者不适用于 Kotlin 的 object
s。为了让 Dagger 注入依赖项,你必须以某种方式提供一个 MainApp
实例:
init {
mainApp.appComponent.inject(this)
}
这没有多大意义,因为您想首先注入它(作为 Context
)。
因此,您必须手动满足依赖关系并且不要在这个中使用 Dagger 或将 object
想法抛在脑后,仅使用标准 class 并让 Dagger 处理其范围:
@Singleton
class Manager @Inject constructor(private val context: Context) {
}
唯一的缺点是您必须将一个 Manager
实例(由 Dagger 创建)注入到每个需要使用它的 class 中,而不是静态调用它的方法。
这是因为你没有在你的 AppModule.kt 中注入你的经理 class 并且你还需要传递上下文。
就像这样:
@Module
class AppModule(private val application: Application) {
@Singleton
@Provides
fun providesManager(): Manager {
return Manager(application.applicationContext)
}
}
显然您需要将您的经理 class 更改为:
@Singleton
class Manager @Inject constructor(context: Context) {
//here you can use your context
}
它应该可以工作
补充:
您可以在 AppComponent.kt 中删除此行:
fun context(): Context
因为没有必要也没有用
唯一的缺点是您需要在每个 activity/fragment 中使用您的管理器 class
就像@jsamol说的
https://dagger.dev/dagger-1-migration.html
Dagger 2 does not support static injection
你可以试试
object Test {
var context: Context = MainApp.getComponent().context()
}
不要将 Android 上下文 类 放在静态字段中,因为这是内存泄漏。
因此,您也可以尝试围绕上下文创建包装器并按照其他人的建议提供依赖项。
我正在尝试使用 Dagger 2 注入 Context
。
AppComponent.kt:
@Singleton
@Component(
modules = [
AppModule::class
]
)
interface AppComponent {
fun context(): Context
}
AppModule.kt:
@Module
class AppModule(private val application: Application) {
@Provides
@Singleton
fun providesApplicationContext(): Context = application
}
MainApp.kt:
class MainApp : Application() {
lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
appComponent = initDagger()
}
private fun initDagger() = DaggerAppComponent.builder()
.appModule(AppModule(this))
.build()
}
Manager.kt: (Class 我要注入的地方 Context
)
object Manager {
@Inject
lateinit var context: Context
}
但是,我收到以下错误:
error: Dagger does not support injection into static fields
public static android.content.Context context;
^
这是因为我使用的是 object
(单例)吗?
如果您对问题有任何疑问,请在下面发表评论。谢谢。
Is this because I am using an
object
(Singleton)?
是的,object
s 的属性是 Java 的静态字段。您的 Manager
class 将反编译为类似于以下内容的内容:
public final class Manager {
@Inject
@NotNull
public static Context context;
public static final Manager INSTANCE;
static {
INSTANCE = new Manager();
}
private Manager() {
}
@NotNull
public final Context getContext() {
return context;
}
public final setContext(Context var1) {
context = var1;
}
}
而 Dagger 2 只是 does not support injection into static fields
。然而,即使 Dagger 让你这样做,依赖性也不会得到满足。那是因为 Dagger 将无法注入到一个对象中,除非被明确告知这样做(就像你在注入到活动中时所做的那样)或自己创建对象。显然后者不适用于 Kotlin 的 object
s。为了让 Dagger 注入依赖项,你必须以某种方式提供一个 MainApp
实例:
init {
mainApp.appComponent.inject(this)
}
这没有多大意义,因为您想首先注入它(作为 Context
)。
因此,您必须手动满足依赖关系并且不要在这个中使用 Dagger 或将 object
想法抛在脑后,仅使用标准 class 并让 Dagger 处理其范围:
@Singleton
class Manager @Inject constructor(private val context: Context) {
}
唯一的缺点是您必须将一个 Manager
实例(由 Dagger 创建)注入到每个需要使用它的 class 中,而不是静态调用它的方法。
这是因为你没有在你的 AppModule.kt 中注入你的经理 class 并且你还需要传递上下文。
就像这样:
@Module
class AppModule(private val application: Application) {
@Singleton
@Provides
fun providesManager(): Manager {
return Manager(application.applicationContext)
}
}
显然您需要将您的经理 class 更改为:
@Singleton
class Manager @Inject constructor(context: Context) {
//here you can use your context
}
它应该可以工作
补充:
您可以在 AppComponent.kt 中删除此行:
fun context(): Context
因为没有必要也没有用
唯一的缺点是您需要在每个 activity/fragment 中使用您的管理器 class
就像@jsamol说的
https://dagger.dev/dagger-1-migration.html
Dagger 2 does not support static injection
你可以试试
object Test {
var context: Context = MainApp.getComponent().context()
}
不要将 Android 上下文 类 放在静态字段中,因为这是内存泄漏。
因此,您也可以尝试围绕上下文创建包装器并按照其他人的建议提供依赖项。