dagger2 學習(一)

前言

該部分代碼

記錄一下自己的基本的認識,Dagger 2 的目的是為了解決依賴問題

當我們申明一個 User mUser 對象 始腾,此時mUser 并未實例化梭冠,而當我們需要實例化的時候桶雀,則需要調用new User()

而使用Dagger 2 的時候矿酵,我們只需要 @inject User mUser 然后在Activity中調用DaggerXXXX....inject(this)即可(假設是Activity唬复,也可以是其他任何類),如下

@User mUser;
@ClassRoom mClassRoom;
...

DaggerXXXX....inject(this)// 只需要調用一次即可
...
mUser.get...
mClassRomm.get...

那為什么不直接new User() 呢全肮,因為會面對一個依賴問題敞咧,而下面的例子并沒有突出解決這個問題,所以暫且擱置不寫辜腺,討論到 @Module 時繼續(xù)討論( 面對 new User(params...) 時休建,需要其他依賴時, 配合 @Module 這個注解進行使用评疗,會顯得更干凈)测砂。

下面的記錄就是最簡單的注入,主要搞定了 new User() 這類無依賴的注入問題

Dagger 2 基本使用

1.@inject 使用百匆, 一共兩種使用地方

(1) 標記被注入的對象的構造方法
public class User {
    int age;
    @Inject// 標注構造方法
    public User(){
    }
  
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
(2) 標記注入目標處
public class MainActivity extends AppCompatActivity {


    TextView mUserAgeTv;
    @Inject User mUser;// 標注注入的對象


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUserAgeTv = (TextView) findViewById(R.id.user_age_tv);
    }
}

這樣標注出了兩個地方砌些,一個被注入對象的構造方法,一個需要注入的對象加匈,但是相互之間是沒有關聯的

寫完這兩個類存璃,編譯后,看一下生成的具體代碼雕拼,驗證一下

(3) @Inject public User()... 后生成的代碼
public enum User_Factory implements Factory<User> {
  INSTANCE;

  @Override
  public User get() {
    return new User();// 真正生成 User 對象的地方
  }

  public static Factory<User> create() {
    return INSTANCE;// 返還User_Factory 對象
  }
}
(4) @Inject User mUser 生成的代碼
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final Provider<User> mUserProvider;// 用來提供User對象的 Provider

  public MainActivity_MembersInjector(Provider<User> mUserProvider) {
    assert mUserProvider != null;
    this.mUserProvider = mUserProvider;
  }

  public static MembersInjector<MainActivity> create(Provider<User> mUserProvider) {
    return new MainActivity_MembersInjector(mUserProvider);
  }

  @Override
  public void injectMembers(MainActivity instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    // 看起來像注入的地方 調用了 userProvider 然后調用了 get
    instance.mUser = mUserProvider.get();
  }

  public static void injectMUser(MainActivity instance, Provider<User> mUserProvider) {
    // 這個也是看起來像注入的地方 調用了 userProvider 然后調用了 get
    instance.mUser = mUserProvider.get();
  }
}

仔細看纵东,發(fā)現兩者生成的代碼現在是無關的,接下來引入連接的注解

2.@Component 使用啥寇,連接上述的兩個地方偎球,進行注入

(1)使用

加入一個新的類,如下

@Component // 注解標記
public interface UserComponent {
    void injectTo(MainActivity mainActivity);
  // 注意此處方法的參數 MainActivity 示姿,由此標記處要注入的類甜橱,而方法名其實可以是任何名字
  // 被 @Component 標注的類逊笆,其具體編譯后生成的代碼栈戳,會有具體的實現類來處理,參考下文
}

看文檔难裆,只知道這是一個連接的子檀,也不知道具體怎么連接的,只知道會生成一個DaggerUserComponent 類乃戈,生成代碼在具體調用分析處褂痰,可具體參考

MainActivity加入 DaggerUserComponent.builder().build().injectTo(this) 就可以注入成功,如下:

MainActivity.java
  

public class MainActivity extends AppCompatActivity {
    TextView mUserAgeTv;
    @Inject User mUser;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUserAgeTv = (TextView) findViewById(R.id.user_age_tv);// 加入這句
        DaggerUserComponent.builder().build().injectTo(this);
        mUserAgeTv.setText("" + mUser.getAge());
    }
}
(2)那就結合調用整體症虑,具體看下生成的代碼吧

DaggerUserComponent.builder().build().injectTo(this);

調用主要分兩條線缩歪,看注釋

  • ..builder().build()

    1 -> 2 步驟 生成一個 DaggerUserComponent 對象,同時實例化出 mainActivityMembersInjector

  • ..injectTo(this);

    3 步驟 是調用 MainActivity_MembersInjector 進行真正的注入

DaggerUserComponent.java
  

public final class DaggerUserComponent implements UserComponent {
  private MembersInjector<MainActivity> mainActivityMembersInjector;

  private DaggerUserComponent(Builder builder) {
    assert builder != null;
    initialize(builder);//2.1 初始化 builder 對象
  }

  public static Builder builder() {
    return new Builder();// 1. 首先生成一個 Builder 對象
  }

  public static UserComponent create() {
    return builder().build();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {
    // 2.2 關鍵處谍憔,它調用的是之前生成 MainActivity_MembersInjector 的 create 方法
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create(User_Factory.create());
  }

  @Override
  public void injectTo(MainActivity mainActivity) {//3. 最后調用 injectTo 方法
    // 3.1 mainActivityMembersInjector 它由 2.2 轉換出來
    mainActivityMembersInjector.injectMembers(mainActivity);
  }

  public static final class Builder {
    private Builder() {}

    public UserComponent build() {
      return new DaggerUserComponent(this);//2. 生成一個 DaggerUserComponent 對象
    }
  }
}

綜上匪蝙,整個連接過程就出來了

下圖中 黃色部分主籍,就是builder().build() 構建出MainActivity_MembersInjector,中間調用了 User_Factory 來生成mUserProvider

下圖紫色部分逛球,就是injectTo() 進行注入千元,根據構建出的MainActivity_MembersInjector,獲取 User 構建的實例颤绕,進行賦值

dagger2學習(一)

最后

整個記錄主要寫了 Dagger 2 最基本的使用幸海,處理了 new User() 此類操作。

當然這不是 Dagger 2 的精華部分奥务,此處主要是為了看其生成的代碼物独,及其基本的使用。

其生成的對應關系如下:

@User mUser ===> User_Factory.java

@User public User(){} ===> MainActivity_MembersInjector.java (其中的 Provider<User> mUserProvider )

@Component UserComponent{...} ===> DaggerUserComponent.java

其具體作用在上面的代碼注釋分析中已經寫了汗洒,此處不重復

以上议纯。

一家之言,如有錯誤溢谤,輕噴瞻凤。

該部分代碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市世杀,隨后出現的幾起案子阀参,更是在濱河造成了極大的恐慌,老刑警劉巖瞻坝,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛛壳,死亡現場離奇詭異,居然都是意外死亡所刀,警方通過查閱死者的電腦和手機衙荐,發(fā)現死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浮创,“玉大人忧吟,你說我怎么就攤上這事≌杜” “怎么了溜族?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長垦沉。 經常有香客問我煌抒,道長,這世上最難降的妖魔是什么厕倍? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任寡壮,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘况既。我一直安慰自己屋群,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布坏挠。 她就那樣靜靜地躺著芍躏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪降狠。 梳的紋絲不亂的頭發(fā)上对竣,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音榜配,去河邊找鬼否纬。 笑死,一個胖子當著我的面吹牛蛋褥,可吹牛的內容都是我干的临燃。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼烙心,長吁一口氣:“原來是場噩夢啊……” “哼膜廊!你這毒婦竟也來了?” 一聲冷哼從身側響起淫茵,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤爪瓜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后匙瘪,有當地人在樹林里發(fā)現了一具尸體铆铆,經...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年丹喻,在試婚紗的時候發(fā)現自己被綠了薄货。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡碍论,死狀恐怖谅猾,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情骑冗,我是刑警寧澤赊瞬,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布先煎,位于F島的核電站贼涩,受9級特大地震影響,放射性物質發(fā)生泄漏薯蝎。R本人自食惡果不足惜遥倦,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧袒哥,春花似錦缩筛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至却紧,卻和暖如春桐臊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晓殊。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工断凶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巫俺。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓认烁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親介汹。 傳聞我的和親對象是個殘疾皇子却嗡,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內容

  • Dagger2 轉載請注明原作者,如果你覺得這篇文章對你有幫助或啟發(fā)嘹承,可以關注打賞稽穆。 前言本文翻譯自Google ...
    輕云時解被占用了閱讀 6,660評論 4 31
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現赶撰,斷路器舌镶,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 本文更新于2017年11月15日閱讀本文大概需要三分半。 前言 dagger出來已經很長時間了豪娜,技術的更新日新月異...
    月下溪明閱讀 2,856評論 1 9
  • 當曙光爬上黎明的窗臺餐胀,緋紅的云霞旖旎了窗外的天空,我子彈般彈起瘤载,破門而出否灾,一頭扎進冷嗖嗖的校園,急切地作別連日的陰...
    慕容蘭馨閱讀 307評論 0 4
  • 前些天,學校里樓管大叔拿著智能手機讓我?guī)兔λ岩徊俊渡臣忆骸房胬辍U垓v了一會扣汪,連上了網絡并教給他。事后我不禁感嘆這是為什...
    時間與區(qū)間閱讀 258評論 0 0