簡體   English   中英

Dagger 2 在 Kotlin 對象中注入上下文

[英]Dagger 2 Inject Context in Kotlin Object

我正在嘗試使用 Dagger 2 注入Context

應用組件.kt:

@Singleton
@Component(
    modules = [
        AppModule::class
    ]
)
interface AppComponent {
    fun context(): Context
}

應用模塊.kt:

@Module
class AppModule(private val application: Application) {

    @Provides
    @Singleton
    fun providesApplicationContext(): Context = application
}

主應用程序.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:(我想注入Context

object Manager {

    @Inject
    lateinit var context: Context
}

但是,我收到以下錯誤:

error: Dagger does not support injection into static fields
    public static android.content.Context context;
                                          ^

這是因為我正在使用一個object (單例)嗎? 如果您對問題有任何疑問,請在下面發表評論。 謝謝你。

這是因為我正在使用一個object (單例)嗎?

是的, object的屬性是底層 Java 的靜態字段。 您的Manager類將反編譯為類似於:

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 為了讓 Dagger 注入依賴,你必須以某種方式提供一個MainApp實例:

init {
    mainApp.appComponent.inject(this)
}

這沒有多大意義,因為您首先想注入它(作為Context )。

因此,您必須手動滿足依賴關系並且不要在此中使用 Dagger,或者將object想法拋在腦后,僅使用標准類並讓 Dagger 處理其范圍:

@Singleton
class Manager @Inject constructor(private val context: Context) {

}

唯一的缺點是您必須將Manager實例(由 Dagger 創建)注入每個需要使用它的類中,而不是靜態調用其方法。

這是因為您沒有在 AppModule.kt 中注入您的 Manager 類,並且您還需要傳遞上下文。

像這樣:

@Module
class AppModule(private val application: Application) {

    @Singleton
    @Provides
    fun providesManager(): Manager {
        return Manager(application.applicationContext)
    }
} 

顯然,您需要將 Manager 類更改為:

@Singleton
class Manager @Inject constructor(context: Context) {
    //here you can use your context
}

它應該工作

額外的:

您可以在 AppComponent.kt 中刪除此行:

fun context(): Context

因為沒有必要也沒有使用

唯一的缺點是您需要在要使用它的每個活動/片段中注入您的 Manager 類

就像@jsamol 說的

https://dagger.dev/dagger-1-migration.html

Dagger 2 不支持靜態注入

你可以嘗試類似的東西

object Test {
    var context: Context = MainApp.getComponent().context()
}

不要將 Android 上下文類放在靜態字段中,因為它會導致內存泄漏

因此,您也可以嘗試圍繞上下文創建一個 Wrapper 並按照其他人的建議提供依賴項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM