Dagger2使用简析
引言在正式开始见解dagger2之前,我们先看一个例子。 public class Engine { //车的引擎
public Engine(){}
public void run(){
System.out.println(" Engine ------------> run : "+hashCode());
}
}
public class Car{ //每台车都需要一个引擎
Engine engine;
public Car(){
engine = new Engine();
}
public void run(){
engine.run();
}
}
我们用下图表示两者关系 public class Car {
Engine mEngine;
public Car(Engine engine){
mEngine = engine;
}
public void run(){
mEngine.run();
}
}
现在不一样,我们的发动机不是和汽车一起制造的,而变成组装了。是在外面造好之后,再安装进来,他们逻辑关系图就成了以下这样: 使用依赖注入的优势是什么呢? 当然,除了这些优点之外还有一些缺点。其中一个缺点是会产生很大的模版代码。使用依赖注入框架时,也会增加学习成本。 下面我们开始真正介绍dagger2这个在java和android上的依赖注入框架。 Dagger2Dagger2是Dagger1的分支,dagger1由Square公司开发,dagger2由谷歌公司接手开发,目前的版本是2.7。Dagger2解决问题的基本思想是:利用编译器apt工具自动生成部分代码和自己手写代码混合达到看似所有的产生和提供依赖的代码都是手写的样子。值得一提的是,dagger2没有用到java反射技术,所以性能相比dagger1有大大的提高。 依赖注入(Dependency Injection简称ID): 就是目标类(目标类需要进行依赖初始化的类)中所依赖的其他的类的初始化过程,不是通过手动编码的方式创建,而是通过技术手段可以把其他的类的已经初始化好的实例自动注入到目标类中。 dagger2注解:要学习Dagger2,就必须要知道下面这些注解和这其中的每一个概念: dagger2使用gradle添加依赖:项目gradle里添加apt工具依赖: classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
app的gradle里添加dagger2依赖: apply plugin: 'com.neenbedankt.android-apt'//添加插件
//添加依赖
compile 'com.google.dagger:dagger:2.7'
apt 'com.google.dagger:dagger-compiler:2.7'
使用:@Inject注解,在Dagger 2中有3种不同的方式来提供依赖 自定义依赖类: public class Engine {
//注意这里放在构造器上,如果这个构造器有参数,则它的参数需要被注入,
//同时意味着这个类可以被注入到别的类里
@Inject
public Engine(){
}
public void run(){
System.out.println(" Engine ------------> run : "+hashCode());
}
}
自定义需要注入依赖的类: public class Car {
@Inject //放在属性成员上,代表这个成员需要被依赖注入
public Engine mEngine;
public Car(){
}
public void run(){
mEngine.run();
}
}
有了上面这两步后,dagger2就可以开始工作了么?,当然不行,dagger2无法聪明到自己去找到Car中正确的Engine类,我们还需要有一个类来告诉dagger2到什么地方去找到需要的依赖。那就是@Component注解。 定义依赖注入的桥梁Component类: 那我们看看这桥梁是怎么工作的:
代码如下: /** * 注意这里Component()参数里没有用到@Module类,这样也是可行的, * 因为上面Engine类里面在构造器上定义@inject注解,相当于已 * 经告诉了dagger2从哪里去找依赖,否则必须制定@Module类。 */
@Component()
public interface CarComponent {//这个类名不固定,但这样更易读
// 注入具体的类中(方法名可随意取,重要的是参数)
void inject(Car car);
}
有了Component桥梁后,就是使用这个component,进行依赖注入了,修改上面Car类,如下: public class Car {
@Inject
public Engine mEngine;
public Car(){
//特别注意DaggerCarComponent是Dagger2自动生成的
CarComponent carComponent = DaggerCarComponent.builder().build();
//进行注入
carComponent.inject(this);
}
public void run(){
mEngine.run();
}
}
通过以上步骤,一个简单的dagger2依赖注入就完成了。我们可以随便new一个Car出来使用,而不用担心Engine为空了。但上面只是一个特例,Engine类是我们自己写的,我们能在其构造函数上标注@Inject注解,如果我们的依赖是第三方库中的类呢,比如OkHttpClient,这里我们就要用到@Module注解了,下面看一个完整例子: public class HttpHelper {
@Inject //需要依赖注入
OkHttpClient client;
private HttpHelper(){
//这里进行注入
DaggerHttpHelperComponent.builder().build().inject(this);
}
public static HttpHelper getInstance(){
return Holder.httpHelper;
}
private static class Holder{
public static HttpHelper httpHelper = new HttpHelper();
}
//get请求
public void get(String url,final Listener listener){
final Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call,IOException e) {
listener.onFailed();
}
@Override
public void onResponse(Call call,Response response) throws IOException {
final String s = response.body().string();
listener.onSuccess(s);
}
});
}
//请求回调
public interface Listener{
void onSuccess(String response);
void onFailed();
}
}
再添加一个module类提供上面需要被注入的依赖 @Module
public class HttpHelperModule {
@Provides //必须用这个标注
@Singleton //注意这里代表是单例
OkHttpClient provideOkHttpClient(){
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(60 * 1000,TimeUnit.MILLISECONDS)
.readTimeout(60 * 1000,TimeUnit.MILLISECONDS);
return builder.build();
}
}
添加一个component类,将上面的module和inject联系起来: @Component(modules = HttpHelperModule.class)
@Singleton //module里面添加了Singleton,则component里面必须也要添加
public interface HttpHelperComponent {
void inject(HttpHelper helper);
}
有了module和component后,dagger2就会自动帮我们生成DaggerHttpHelperComponent类,所以就可以调用 : DaggerHttpHelperComponent.builder().build().inject(this);
完成依赖注入。其原理就是使用apt在编译时,在build目录下产生相应的java源代码,如上面的DaggerHttpHelperComponent.java代码,大家可以自行分析下。 总结Inject,Component,Module,Provides是dagger2中的最基础最核心的知识点。奠定了dagger2的整个依赖注入框架:
github代码:https://github.com/nickyangjun/Dagger2Test 更多精彩Android技术可以关注我们的微信公众号,扫一扫下方的二维码或搜索关注公共号: Android老鸟 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |