鸡汤:感到迷茫是因为你没有给自己做好人生规划
接上一章的内容,如果还没看过的朋友,
请点
本章内容
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开发路上一只稍大一点的菜鸟,如果各位读者中发现文章中有误之处,请帮忙指出,你的批评和鼓励都是我前进的动力。