目前Dagger有两个分支,一个square维护,一个为Google在前者的基础上开出的分支,即Dagger2。今天我们只谈dagger2。
Dagger2使用原因
Dagger2是一个依赖注入的框架,那什么是依赖注入呢?依赖注入式一种面向对象的编程模式,它的出现是为了降低耦合性,所谓耦合就是类之间依赖关系,也就是降低类之间的依赖关系。
依赖注入原理
在软件工程领域,依赖注入是用于实现控制反转(IoC)的最常见的方式之一。IoC不是什么技术,而是一种设计思想,在Java开发中,IoC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
依赖注入的实现方式:1.构造函数注入 2.setter注入 3.接口注入
Dagger2引入
添加apt插件
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
添加依赖(build.gradle中添加)
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
...
compile 'com.google.dagger:dagger:2.7'
apt 'com.google.dagger:dagger-compiler:2.7'
...
}
这里我们使用的是apt插件
APT(Annotation Processing Tool)是一种处理注释的工具,它对源代码文件进行检测找出其中的Annotation,根据注解自动生成代码。 Annotation处理器在处理Annotation时可以根据源文件中的Annotation生成额外的源文件和其它的文件(文件具体内容由Annotation处理器的编写者决定),APT还会编译生成的源文件和原来的源文件,将它们一起生成class文件
annotationProcessor和android-apt的功能是一样的,它们是替代关系。所以你可能会在其他文章或者项目中看到上面两种依赖的方式,至于他们的区别,链接我会放在文章下方。
Dagger2使用
在项目中绝大多数的使用都是Dagger结合MVP架构使用的,在MVP中使用时非常典型的降耦合的使用。
在MVP模式中activity持有presenter的引用,同时presenter也持有View的引用,这样便于更新UI界面,这样presenter就和activity紧紧的耦合在一起了,而dagger2是依赖注入框架就是耦合的。
新建目录di
activity中代码:
public abstract class BaseActivity extends AppCompatActivity implements IBaseView {
...
@Inject
AlbumDetailPresenter detailPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mActivityComponet = DaggerActivityComponet.builder().activityModule(new ActivityModule(this)).build().inject(this);
}
}
AlbumDetailPresenter中代码:
public class AlbumDetailPresenter implements IAlbumDetailPresenter {
@Injectpublic AlbumDetailPresenter(@ContextLife("Activity") Context context) {this.context = context;
}}
新增ActivityComponent接口:
@Component(modules = ActivityModule.class)
public interface ActivityComponet {
void inject(BaseActivity aty);
}
新增ActivityModule类:
@Module
public class ActivityModule {
private final Activity mActivity;
public ActivityModule(Activity activity) {
mActivity = activity;
}
@Provides
@ContextLife("Activity")
public Context provideContext() {
return mActivity;
}
}
通过直接注解和上述接口和类即可完成Dagger2的依赖注入。在BaseActivity中是通过:
DaggerActivityComponent.builder().activityModule(new ActivityModule(this).build().inject(this))
完成注入的。
注意:添加@inject注解的变量不能被private修饰
我们可以这样理解,被@inject注解的代码存在某种联系,当代码执行到@inject的时候程序会自动进入到这个类的构造方法中,如果正巧这个构造方法也被@inject修饰了,那么系统就会帮我们自动创建对象。
在ActivityComponent接口中我们看到这么一个注解@Component(modules=ActivityModules.class),可见ActivityComponent需要ActivityModule一起才能完成工作。这个类我们也可以理解成是提供参数的,这里我们提供一个上下文给presenter的构造方法。
总结一下
·@Injet 程序会将dagger2会将带有此注解的变量或者构造方法参与到依赖注入当中,dagger2会实例化这个对象。
.@Module 带有该注解的类需要对外提供实例化需要的参数,dagger2在实例化的过程中发现一些参数,dagger2就会去该类中寻找带有@provides注解对应的参数
.@Component 带有该注解的接口或抽象类起到一个中介的作用,就是将带有@Inject的方法或对象和带有@Module的类进行关联
参考:http://blog.csdn.net/xx326664162/article/details/68490059