大家好,我是蒼王。
以下是我這個系列的相關文章,有興趣可以參考一下,可以給個喜歡或者關注我的文章。
[Android]如何做一個崩潰率少於千分之三噶應用app–章節列表
相信有關注我的人,都會看過我第一編介紹的Todo-mvp原始碼體驗,這是基礎編。
這一章的難度理解難度將會非常大。
這個系列的課程適合研發有Android有一年半左右的同學參考。
基於工作的問題,大型公司其實都不怎麼使用這種注入框架,而是直接用程式碼完成解耦的。但是學習期框架架構,對我們瞭解註解的使用和構建學習一些設計模式有著重要的作用。Dagger的設計的確非常精妙。
一.基礎介紹
估計很多新手看Dagger2都會看到一頭霧水,因為Dagger2使用的依賴反轉的設計模式原則。
舉個例子,我去買東西,告訴老闆我需要什麼品類的東西,老闆就說你等著,我拿給你就好了。
這個部分都是老闆幫我們完成了。
推薦一個非常好的Dagger2的入門文章給大家,裡面都是Dagger2基本的使用原理,和一般的架構設計,看完之後估計大家應該不會再一頭霧水。
Google官方MVP+Dagger2架構詳解【從零開始搭建android框架系列(6)】
如果沒有Dagger基礎,而且不看介紹,然後直接看一下的內容,估計你會一頭霧水。(最好下原始碼對著看)
沒Dagger基礎一定要看介紹
沒Dagger基礎一定要看介紹
沒Dagger基礎一定要看介紹
重要的事情說三次!!!
二.原始碼分析
(一).引用相關
關於引用,需要使用android-apt的引用
還有Dagger2所需要的依賴
一開始下載下來,開啟XXActivity的檔案發現都會報紅,然後需要我們make projects一次,Dagger2會自動生成一些Dagger注入的類。
編譯完成後,我們會在apt的資料夾裡面,看到生成的Dagger程式碼,很顯然是通過apt程式碼編寫的程式碼。
這裡的套路和MVVM有點相似,但是MVVM是原始碼就提供MVVM的自動編碼,而Dagger2需要apt去做。
(二).Application註解
我們看自定義的ToDoApplication,可以簡單到看到mRepositoryComponnet是資料來源在這裡宣告為全域性的變數
這裡會引用到自定義的ApplicationModule實體類,外面的變數通過provideContext獲取ApplicationContext引數。
(三).Component註解
我們這裡先以TaskDetailActivity為例吧(這裡不對Dagger2的注入方式再進行介紹,可以看我基礎介紹裡面的網址學習)
我們看到DaggerTaskDetailComponent是使用了建造者模式的鏈式結構。
我們看到的是自動生成的DaggerTaskDetailComponent是繼承TaskDetailComponent
我們看到起使用@Provider就會生成Provider型別的變數
使用@Inject標誌的變數就會被宣告為MembersInjector的變數
因為使用了inject(this)還會將整個TaskDetailActivity宣告為MembersInjector的變數
看到這裡應該很清楚,起初始化的時候,還會呼叫intialize方法
這裡很明顯,每個變數都會通過XXXFactory.create來獲取相應的建立出來(這裡使用很明顯就是工廠模式)
Module宣告的實體主要是用到了工廠模式生成
使用inject(this)的時候會呼叫injectMembers的方法替換變數
深入到TaskDetailActivity_MembersInjector實現類,初始Presenter物件
這裡初始化的時候會輸入PresenterProvider的變數
其是通過靜態的create方法做成工廠的。
這裡是DaggerTaskDetailComponent的intialize的時候會載入Provider
繼續是工廠類建立
其會建立出一個工廠類的方法出來。
這裡繼續下來是很酷的是建造者模式Buidler。
可以看出Component的核心原始碼系建造者模式。
這裡需要確立的是build一定是在inject之前的,先輸入引數建造才能注入。
Presenter是什麼時候被初始化的呢?
我們看到TaskActivity裡面注入Presenter
獲取taskPresenterModule的物件
TaskPresenter裡面構造
(1)關於tasksPresenterMembersInjector的獲取
我們看到這裡初始化
然後在TaskPresenter_Factory通過get方法來獲取
這裡還涉及到一個Listeners的方法
其實現是在TasksPresenter裡面
(2)關於TaskDetailPresenter
TaskDetailPresenter的獲取是在TaskDetailActivity
這裡provideTaskIdProvider其引用是provideTaskId
provideTaskDetailContractViewProvider對應的是provideTaskDetailContractView
這裡宣告瞭FragmentScoped的定義域(Scope其定義是單例的定義域)
還有dependencies就是TaskRepositoryComponet的資料來源來源
其getTasksRepositoryProvider 其提供者應該是getTasksRepository.
其實體物件獲取方式,是通過初始化的時候傳入TasksRepositoryComponent的實體
傳入資料提供實體
在自定義的Application中建立資料實體
(四).關於資料實體TasksRepository
我們分為近端和遠端資料
這裡@Qualifer是自定義命名的註解
@宣告資料單例
初始化中帶有本地和遠端的註解物件
在DaggerTasksRepositoryComponent中聯通這些註解物件
通過getTasksRepository獲取到實體到資料流實體
設定通過單例@Singleton的方法獲取遠端和近端的資料
其單例的宣告是通過enum列舉,然後宣告INSTANCE的方式,宣告單例的。
這裡特別說名一下一個沒有scope的元件component不可以依賴一個有scope的元件component。子元件和父元件的scope不能相同。我們通常的ApplicationComponent都會使用Singleton註解(),也就會是說我們如果自定義component必須有自己的scope。
三.總結
Dagger2註解,框架最重要理解的就是依賴倒置的設計原則。
Dagger2原始碼的套路
Module->Factory.create 工廠建立
Component-> XXXComponent.Bulider 建造者模式
Singleton Scoped-> 利用enum和INSTANCE標示 單例模式
理解這些設計模式,一旦你真的看懂Dagger2的設計模式,你會覺得Dagger2的設計非常精妙。可以理解其Apt的註解編寫的設計真的非常值得學習,以後有機會會給大家分享Apt編寫程式碼的一些詳解。
這次的原始碼分析就到這裡
下一節應該會分析MVP +RXJava的原始碼,敬請期待!!!
我建立了一個關於Android架構學習的群,裡面可以進一步進行元件化學習和架構思想的的交流。
群號是316556016,也可以掃碼進群。我在這裡期待你們的加入!!!