作者:Antonio Leiva 時間:Apr 11, 2017 原文鏈接:https://antonioleiva.com/dagger-android-kotlin/ 在Android上,創建去耦以及容易測試代碼的幾乎每位遲早都要訴諸Dagger。 雖然,在Kotlin中設置Dagger有一些不 ...
時間:Apr 11, 2017
原文鏈接:https://antonioleiva.com/dagger-android-kotlin/
在Android上,創建去耦以及容易測試代碼的幾乎每位遲早都要訴諸Dagger。
雖然,在Kotlin中設置Dagger有一些不同,但是大多數都十分簡單,僅需要幾個步驟。今天我就在這裡講解。
同時要意識到,由於Kotlin的能力,還有其他方法可以解決註入問題,甚至在Kotlin中還有一些專門的庫來解決。
但是Dagger仍然是有效的選擇,即使不是最最通用的,也是其中之一。
提示:
在這篇文章中,我不會解釋怎樣使用Dagger 2,這是已知的。如果你有任何問題,可以閱讀我之前寫過一些關於依賴註入的文章。
用Dagger 2配置項目
如果在你的項目中,你已經配置了Kotlin插件,你需要做的就是配置kapt。
如果你已經使用過Dagger,你大概知道apt.kapt是Kotlin的一個版本,它為Dagger創建了需要的自生成類。
為了配置它,你需要將下麵內容加入build.gradle:
1 kapt { 2 generateStubs = true 3 }
你能夠將其加入在依賴節之前。如果願意,你能夠使用新的實驗性插件,它已經相當穩定了:
1 apply plugin: 'kotlin-kapt'
現在,你就需要加入Dagger編譯器的依賴關係(是使用kapt而不是包括在apk中)和實際的庫:
1 kapt 'com.google.dagger:dagger-compiler:2.5' 2 compile 'com.google.dagger:dagger:2.5'
這樣一切就緒,可以開始使用Dagger。
主模塊的實現
你可能知道,對於主圖形,你需要一個Module和一個Component。
在這個簡單的例子中,應用模塊僅返回應用自己的實例。
為了這樣做,我們將用@Module註解創建一個類,通過構造函數接收應用實例,將其保存到屬性中,用@Provides@Singleton註解的方法返回它。
1 @Module class AppModule(val app: App) { 2 @Provides @Singleton fun provideApp() = app 3 }
你可以看到,即使對於這樣簡單的類,其代碼也要比用Java簡單得多。
接著我們要實現Component,它需要載入一個模塊數組,並且說明誰能夠手動註入它:
1 @Singleton 2 @Component(modules = arrayOf(AppModule::class)) 3 interface AppComponent { 4 fun inject(app: App) 5 }
再就只創建一個App類,它將負責生成圖片:
1 class App : Application() { 2 3 val component: AppComponent by lazy { 4 DaggerAppComponent 5 .builder() 6 .appModule(AppModule(this)) 7 .build() 8 } 9 10 override fun onCreate() { 11 super.onCreate() 12 component.inject(this) 13 } 14 }
這裡看到的有趣的事是,由於lazy聲明,我們能夠在屬性的定義中指定圖形的值,因此就獲得了對該屬性的只讀訪問權。
在component.inject (this)完成前,代碼定義的屬性不會被執行,所以到那時,this已經存在了,就可以安全地創建了。
每個模塊實現的範圍
模塊的範圍僅允許圖部分在其它的對象生命周期中生存。
用這種方法,例如,我們可以在Activity的生存中創建子圖。
我們會用依據需要創自己的建模塊:
1 @Module 2 class HomeModule(val activity: HomeActivity) { 3 }
Subcomponent非常類似前面所述方法,表明它會註入HomeActivity:
1 @Singleton 2 @Subcomponent(modules = arrayOf(HomeModule::class)) 3 interface HomeComponent { 4 fun inject(activity: HomeActivity) 5 }
AppComponent的plus方法,表示這個組件能夠加入到子組件的類型:
1 interface AppComponent { 2 ... 3 fun plus(homeModule: HomeModule): HomeComponent 4 }
現在,你就只需要在HomeActivity中聲明子組件:
1 val component by lazy { app.component.plus(HomeModule(this)) }
你可在setContentView之後註入它:
1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContentView(R.layout.activity_main) 4 component.inject(this) 5 }
如果你想知道app是從哪裡來的,它是一個像這樣擴展屬性:
1 val Activity.app: App 2 get() = application as App
如果您有自己的自定義application,這隻是一種避免每次訪問它的簡單方法。
結論
在Kotlin中,使用Dagger 2也很容易。你再無有理由在Kotlin中去實現一個很大的解耦架構了。
如果你要學習更多的這些並且用Kotlin創建自己的Android APP,就看看免費的指南,學習怎樣建立你的第一個項目,或是直接購買這本書,學習怎樣從頭開始創建一個完整的APP。