學習札記:Dagger2快速上手系列一
學習札記:Dagger2快速上手系列二
一.什麼是Dagger2
Dagger2是Dagger的升級版,是一個依賴注入框架,第一代由大名鼎鼎的Square公司共享出來,第二代則是由谷歌接手後推出的,現在由Google接手維護,傳送門Dagger2的GitHub地址
二.爲什麼使用Dagger2
上面我們說到,Dagger2是一個依賴注入框架,那什麼是依賴注入呢,可以抽象的理解爲其實就是將一個類裏面包含另外一個類實例的引用。
我們常用的在屬性,方法中參數 ,甚至通過接口中抽象方法中的參數等方式都可以實現依賴注入,那爲什麼還要使用Dagger2呢,當然如果是單兵作戰,項目不大的話,不用也沒關係,但是在項目很大,協同工作中,建議還是使用Dagger2,因爲你會發現它會讓你的項目結構清晰,維護起來也更加方便,降低代碼耦合度,另外它是編譯時生成一些代碼,也不會產生性能影響。
三.如何使用Dagger2
1.配置:在項目app目錄下build.gradle的dependencies中加入這兩行
annotationProcessor ‘com.google.dagger:dagger-compiler:2.24’
implementation ‘com.google.dagger:dagger :2:2.24’
2.配置完以後,我們通過一個簡單的例子來走一遍,看一下Dagger2到底哪裏好用了。
這個說一個簡單的場景,比如我們在做註冊的時候,需要本地和服務器存一些數據,我們會有一個管理類,
分別持有本地和服務器操作的類的實例。
/**
管理類
**/
public class SUserManager {
SApiService apiService;
SUserStore userStore;
public SUserManager( SApiService apiService, SUserStore userStore) {
this.apiService =apiService;
this.userStore =userStore;
}
public void register() {
apiService.register();
userStore.register();
}
}
/**
服務器操作
**/
public class SApiService {
public SApiService() {
Log.d(TAG, "SApiService: ");
}
public void register(){
Log.d(TAG, "register: >>>>>>>");
}
}
/**
本地操作
**/
public class SUserStore {
public SUserStore() {
Log.d(TAG, "SUserStore: ");
}
public void register() {
Log.d(TAG, "register: >>>>>>>>");
}
}
一般情況下我們都會這麼去寫,然後在需要引用UserManager地方實例化一個對象,然後進行操作,這樣當然也沒什麼問題,但是如果說我們做一下簡單的調整,比如說我在註冊的時候需要修改一下本地註冊時的參數,就比如說一個上下文對象吧,這個時候是不是要修改UserManger,在調用UserManager實例中的也會去修改。項目小還稍微好點,要是項目大,需要改的東西可能就很多了,甚至會出錯,所以Dagger2就是爲了處理這些問題。
那麼該如果使用Dagger2來解耦呢,讓項目結構更清晰呢。首先我們來看張圖
其實就是我們通過被component註解的接口將被Module註解工廠中的生成的對象注入到Activity等容器中。我們通過代碼理解下這句話。
首先我們要搞個紐帶,也就是被component註解的接口。
@Component(modules = {SUserModule.class})
public interface SUserComponent {
void inject(MainActivity activity);
}
我們在這裏支持持有了Activity中引用,並且在Component引入了SUserModule這個“對象工廠”
@Module
public class SUserModule{
@Provides
public SUserStore provideSuserStrore() {
return new SUserStore ();
}
@Provides
public SApiService provideApiService() {
return new SApiService();
}
@Provides
public SUserManager provideUserManager(SApiService apiService, SUserStore userStore) {
return new SUserManager(apiService, userStore);
}
}
我們在MainActivity中使用Inject註解需要注入的對象實例,然後編譯通過後,使用SUserComponent.create().inject(this),注入就可以使用了。
public class MainActivity extends AppCompatActivity {
@Inject
SUserManager daggerUserManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerSUserComponent.create().inject(this);
daggerUserManager.register();
}
}
這樣咋一看,是變得複雜了,代碼越寫看起來越多,但是實際上當你SUserManager 被多個地方引用時,你基本上只需要改一下SUserModule這個裏面的代碼,這樣是不是讓你的代碼維護起來更加的方便,結構看起來也更加清晰。
好了,簡單的使用就說完了,我們來做個簡單的總結。上面我們主要用到了四個註解,@Module @Provides
@Component @Inject,下面梳理下這幾個註解使用:
@Module:用來註解生成對象的工廠,讓Dagger2知道從哪裏去找對象;
@Provides:用在module工廠中方法的註解,告訴Dagger2我們想要構造對象並提供這些依賴;
@Component:如上圖中描述,是一個紐帶;
@Inject:通常在需要依賴的地方註解。
暫時只整理這麼多,本文如果有不正之處,煩請之處,感謝感謝!