雞湯:感到迷茫是因為你沒有給自己做好人生規劃
接上一章的內容,如果還沒看過的朋友,
請點
本章內容
Dagger2的引入
Dagger2的引入
Dagger2是一個依賴注入框架,那么dagger2能起什么作用呢?
簡單點講就是
dagger2會幫你維護好一些對象,你需要什么對象,可以直接問dagger2要,
當然前提是你已經按照dagger2的要求寫了好這些依賴。
比如:像下圖這種情況,你需要得到result,那你不得不像代碼那樣,先得到c對象,得到c對象,就需要得到b對象,需要得到a對象。
public class Dagger2Test{
private classA a;
private classB b;
private classC c;
private String result;
public void onCreate() {
super.onCreate();
b=new classB(a);
c=new classC(b);
result=c.get(0);
}
}
而使用了dagger2的話,可以寫成這樣
public class Dagger2Test{
//一個直接得到c對象,然后在oncreate中一行代碼搞定
@Inject
classC c;
private TestComponent mComponent;
private String result;
public void onCreate() {
super.onCreate();
mComponent.inject(this);
result=c.get(0);
}
}
Dagger2的引入
在config.gradle(不知道config.gradle如何來的,請看系列文章第0章)設置依賴
//版本號
daggerVersion = '2.2'
javaxAnnotationVersion = '1.0'
//遠程依賴
dependencies = [
daggerCompiler: "com.google.dagger:dagger-compiler:${daggerVersion}",
dagger: "com.google.dagger:dagger:${daggerVersion}",
javaxAnnotation: "javax.annotation:jsr250-api:${javaxAnnotationVersion}"
]
build.gradle下
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
//加入dagger2的apt插件
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
app/build.gradle下
文件頂部
//引入dagger2 的apt插件
apply plugin: 'com.neenbedankt.android-apt'
//添加依賴
apt dependency['daggerCompiler']
compile dependency['dagger']
compile dependency['javaxAnnotation']
做完上述的工作,dagger2就已經引入成功了。
在項目中使用
首先回顧一下在開源項目2中的代碼,在事件的起點view,也就是TodayGankFragment中,有段代碼是這樣的!
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RxFlux rxFlux = RxFlux.init(MyApplication.getApplication());
Dispatcher dispatcher = rxFlux.getDispatcher();
SubscriptionManager manager = rxFlux.getSubscriptionManager();
store = new TodayGankStore(dispatcher);
dispatcher.subscribeRxStore(store);
dispatcher.subscribeRxView(this);
creator = new TodayGankActionCreator(dispatcher, manager);
//view從對應的Creator請求數據
creator.getTodayGank();
}
上述代碼中最重要的,不可或缺的,不能再縮減的代碼有這么幾句
//兩個監聽注冊
dispatcher.subscribeRxStore(store);
dispatcher.subscribeRxView(this);
//view從對應的Creator請求數據
creator.getTodayGank();
兩個subscribe監聽注冊,以及數據請求,數據請求是事件的起點,subscribe是為了之后的數據流轉所必須的。
除了這三行代碼,其他的變量和對象的聲明都可以想辦法放到別處,使得這段代碼變得簡潔。
這個時候Daggar2就可以排上用場了。
首先來整理下依賴,我們的需要的依賴對象或者變量有
RxFlux
dispatcher
manager
store
creator
一個有5個依賴,再根據業務邏輯將5個依賴劃分一下,
RxFlux,dispatcher,manager這三個依賴屬于全局型依賴,就是說很多地方都需要用的到的依賴。
而store和creator只是局部型依賴,所以單獨處理。
全局依賴
定義一個AppComponent類,具體寫法不在累述。
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
//
Dispatcher getDispatcher();
SubscriptionManager getSubscriptManager();
}
AppComponent類提供Dispatcher和SubscriptionManager兩個對象,具體的實現在AppModule類中
@Module
public class AppModule {
private final RxFlux mRxFlux;
public AppModule(MyApplication application) {
mApplication = application;
//初始化RxFlux
mRxFlux = RxFlux.init(application);
}
@Provides
@Singleton
Dispatcher provideDispatcher() {
return mRxFlux.getDispatcher();
}
@Provides
@Singleton
SubscriptionManager provideSubscriptManager() {
return mRxFlux.getSubscriptionManager();
}
}
構造函數里初始化RxFlux,然后借用RxFlux,初始化Dispatcher和SubscriptionManager對象。
調用:
在程序入口MyApplication中使用
public class MyApplication extends Application {
private static AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
initInjector();
}
private void initInjector() {
mAppComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
public static AppComponent getAppComponent() {
return mAppComponent;
}
}
在MyApplication中initInjector()方法執行之后,RxFlux,Dispatcher和SubscriptionManager三個依賴對象就初始化成功了。
接下來還需要store和creator這兩個依賴,
定義一個TodayGankFragmentComponent類
@PerActivity
@Component(dependencies = {AppComponent.class})
public interface TodayGankFragmentComponent {
void inject(TodayGankFragment todayGankFragment);
}
PerActivity類,聲明scope,不然會報錯
@Scope
@Retention(RUNTIME)
public @interface PerActivity {}
在TodayGankFragment中,使用TodayGankFragmentComponent,注意appComponent的時候要把你之前定義好的appComponent對象傳進去,
private void initInjector() {
TodayGankFragmentComponent mComponent= DaggerTodayGankFragmentComponent.builder()
.appComponent(MyApplication.getAppComponent())
.build();
mComponent.inject(this);
}
這個時候你就可以很簡單的聲明對象了,
比如TodayGankStore類中,先在構造方法上加上@Inject注解,表示我能接受一個dispatcher參數,并提供一個TodayGankStore對象,而dispatcher這個對象在最開始的appComponent中就已經初始化完成,
@Inject
public TodayGankStore(Dispatcher dispatcher) {
super(dispatcher);
}
在需求類中,即TodayGankFragment中,聲明TodayGankStore對象store,這個store就是TodayGankStore所提供的,這中間的過程Dagger2會幫你處理。
@Inject TodayGankStore store;
單獨解釋一下@Inject這個注解的作用
1.標記在構造方法上,表示對象提供者
2.標記在目標類中,表示實例對象。
加入了dagger2之后,代碼變化如下,
@Inject TodayGankStore mStore;
@Inject TodayGankActionCreator mActionCreator;
@Inject Dispatcher mDispatcher;
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//RxFlux rxFlux = RxFlux.init(MyApplication.getApplication());
//Dispatcher dispatcher = rxFlux.getDispatcher();
//SubscriptionManager manager = rxFlux.getSubscriptionManager();
//store = new TodayGankStore(dispatcher);
//dispatcher.subscribeRxStore(store);
//dispatcher.subscribeRxView(this);
//creator = new TodayGankActionCreator(dispatcher, manager);
//view從對應的Creator請求數據
//creator.getTodayGank();
mDispatcher.subscribeRxStore(mStore);
mDispatcher.subscribeRxView(this);
mActionCreator.getTodayGank();
}
注釋的代碼是沒加Dagger2之前的,可以明顯的看出依賴關系簡單了很多,代碼邏輯也清晰了許多。
Dagger2還是能夠給代碼帶來挺大的變化的。
本來還想再寫一點基類封裝的內容,不過由于部分代碼和業務邏輯關系比較緊,要寫的話,內容還有不少。
所以留到下次再講吧!
本人也只是Android開發路上一只稍大一點的菜鳥,如果各位讀者中發現文章中有誤之處,請幫忙指出,你的批評和鼓勵都是我前進的動力。
寫在文末:如果讀者朋友有什么問題或者意見可以在評論里指出.
代碼地址為https://github.com/niknowzcd/FluxDemo3