從實例出發(fā)理解Dagger2(二)

You need to tell the Dagger2 how to create your dependency instances of what each one depends on. Dagger2 can't figure everything else, it's not magic ,it can't know the constructor arguments.
Dagger2需要你告訴他如何去創(chuàng)建一個對象,并且如何獲取對象所需要的的依賴。Dagger2并不是什么神秘的技術(shù),他就是負(fù)責(zé)創(chuàng)建對象而已。

好,理清了Dagger2的作用后讓我們開始從Application入手吧。

創(chuàng)建Dagger graph

創(chuàng)建這個Dagger graph的作用是生成GitHubServicePicasso對象。所以他們內(nèi)部依賴的對象OKHttp、Timber、Gson等也會一并被創(chuàng)建。把需要創(chuàng)建的對象大致分成兩類,網(wǎng)絡(luò)相關(guān)的Retrofit和圖片加載相關(guān)的Picasso。這兩類又會有公共的部分,比如OKHttp。那么如何創(chuàng)建Dagger graph呢?

1.創(chuàng)建Component

Component是一個public的接口,需要向外暴露獲取GithubService和Picasso實例的方法。其余GithubService和Picasso所需要依賴的對象比如OKHttp等應(yīng)該被隱藏,防止這些類散落到代碼中(flying off into the sunset)。讓我們創(chuàng)建一個Component,GithubApplicationComponet

image.png

需要注意到的時,要在這個interface上加@Component的注解,這樣Dagger2才能知道這是一個Component。這里面兩個方法就告訴了graph,這個Component的作用就是提供Picasso和GithubService。當(dāng)編譯這個項目的時候,Dagger就會自動生成一個GithubApplicationComponet的子類,用于提供Picasso和GithubService。但是這些類是從哪里產(chǎn)生的呢?Dagger并不能憑空產(chǎn)生這些類。這里就需要用Module來告訴Component如何得到這些類。

2.創(chuàng)建Module

首先想想創(chuàng)建Picasso和GithubService需要哪些東西呢?上面提到的OKHttp、Timber、Gson還有Context等。這些都需要通過Module來提供。還有GithubService和Picasso本身也要通過Module提供。
首先先編寫提供GithubService的Module。代碼如下:

image.png

和上面Component一樣,你要加上@Module Dagger才知道這是一個Module,這是給Component提供類的。
那提供了GithubService就行了嗎?不行的,你還要告訴Dagger從哪里獲取GithubService,說白了,到哪個Module去獲取GithubService這個類。如圖:
image.png

注意哈,在@Component后面加了(modules = {GithubServiceModule.class}),這樣Component就知道從GithubServiceModule這個Module里能獲得GithubServiceModule。至于怎么知道的?當(dāng)然是根據(jù)類型判斷呀。你看GithubServiceModule就一個方法返回GithubService,不用它用誰啊。那要是非得抬杠,我又添加一個方法,也是返回GithubService類型的呢?先別著急嘛,凡事都是慢慢來,Dagger準(zhǔn)備好方法來應(yīng)對這樣的問題了。讓我們先假裝剛剛沒有發(fā)生那個抬杠。

GithubServiceModule中的githubService()方法如何返回GithubService呢?

image.png

對,直接把Application中創(chuàng)建GithubService的代碼考過來。但是好像缺gitHubRetrofit怎么辦呢?new一個不就解決了嘛!
image.png

臥槽,好像又缺O(jiān)KHttp和Gson呀。怎么辦?還new一個?騷年,此情此景你不覺得熟悉嗎?不熟悉?剛才在Application里面不就是這么干的嗎?連環(huán)new下去,又是一段噩夢代碼呀~所以一定不是這么干的!不能new那我就只能通過githubService(Retrofit retrofit)傳一個Retrofit進(jìn)來了。等等,此情此景好像又在哪里見過!這不就是第一篇文章說的依賴注入Picasso嘛!既然是依賴注入那就統(tǒng)統(tǒng)交給Dagger去解決吧。見代碼:
image.png

可以看到gsonretrofit()方法分別返回所需的Retrofit和Gson。但是問題又來了OKHttp是怎么解決的呀?別的Module提供的。是的,Module也能從其他Module中獲取對象。@Module后面(includes = NetworkModule.class)了嗎?就是從這里獲取的OKHttp。至于怎么獲取的,和這個GithubServiceModule大同小異。至于為什么要放到不同的Module中,當(dāng)然是為了更加合理劃分Module(臥槽,感覺像是廢話。。。)
仿佛看見@Provides在對我笑??!這又是個什么鬼?其實Module中不是所有的方法都是依賴所需要的類的,那么Dagger就沒有必要給這些方法做特殊的處理,也就沒有必要加上@Provides注解了(比如這里加上一個根據(jù)Debug環(huán)境提供不同BaseUrl的方法,其他地方也不會用到BaseUrl,那么這個提供BaseUrl的方法就沒有必要加@Provides)。換句話說,如果Module中的方法是提供注入依賴對象的,那么就需要加上@Provides注解。

最后放上獲取OKHttp的NetWorkModule的代碼:

image.png

哎?這里還有個獲取Context的Module呢。那么怎么注入Context呢?在ContextModule中new一個?不可能,一定是有特殊的技巧的!具體怎么辦,我們下回見!

相關(guān)文章:
從實例出發(fā)理解Dagger2(一)
從實例出發(fā)理解Dagger2(二)
從實例出發(fā)理解Dagger2(三)
從實例出發(fā)理解Dagger2(四)
從實例出發(fā)理解Dagger2(五)
從實例出發(fā)理解Dagger2(六)
從實例出發(fā)理解Dagger2(七)

參考資料:https://www.youtube.com/watch?v=qxm-1eUMt_c&list=PLuR1PJnGR-Ih-HXnGSpnqjdhdvqcwhfFU&index=2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容