前言
記錄一下自己的基本的認識,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
構建的實例颤绕,進行賦值
最后
整個記錄主要寫了 Dagger 2 最基本的使用幸海,處理了 new User()
此類操作。
當然這不是 Dagger 2
的精華部分奥务,此處主要是為了看其生成的代碼物独,及其基本的使用。
其生成的對應關系如下:
@User mUser
===> User_Factory.java
@User public User(){}
===> MainActivity_MembersInjector.java
(其中的 Provider<User> mUserProvider
)
@Component UserComponent{...}
===> DaggerUserComponent.java
其具體作用在上面的代碼注釋分析中已經寫了汗洒,此處不重復
以上议纯。
一家之言,如有錯誤溢谤,輕噴瞻凤。