Dagger2-初认识一

背景:

有什么能比那把黄油刀(butterknife)更加犀利的名字惟有dagger了html

最先的版本Dagger1 由Square公司开发。依赖注入框架主要用于模块间解耦,提升代码的健壮性和可维护性。Dagger 这个库的取名不只仅来自它的本意“匕首”同时也暗示了它的原理java

Dagger2 是一个Android依赖注入框架,由谷歌开发,由于主流是Dagger2因此接下来咱们直接学习如何使用它android

认识依赖注入

说了那么多,那到底依赖注入是什么呢?上代码:git

public class MainActivity extends AppCompatActivity {
    User user;

    public void setUser(User user) {
        this.user = user;
    }复制代码

依赖:MainActivity 包含了一个User对象,咱们就说MainActivity 依赖于user;
注入:由于user对象是经过传递初始的,不是直接new出的对象,因此这样的方式就叫作注入;
经过上面简单的一小段代码估计你们对依赖注入有了了解,经过依赖注入能够有效的减小咱们的耦合,既然这样能够实现依赖注入,为何还须要dagger这样的第三方库处理呢?github

1.增长开发效率、省去重复的简单体力劳动

首先new一个实例的过程是一个重复的简单体力劳动,dagger2彻底能够把new一个实例的工做作了,所以咱们把主要精力集中在关键业务上、同时也能增长开发效率上。
省去写单例的方法,而且也不须要担忧本身写的单例方法是否线程安全,本身写的单例是懒汉模式仍是饿汉模式。由于dagger2均可以把这些工做作了。设计模式

2.更好的管理类实例

每一个app中的ApplicationComponent管理整个app的全局类实例,全部的全局类实例都统一交给ApplicationComponent管理,而且它们的生命周期与app的生命周期同样。
每一个页面对应本身的Component,页面Component管理着本身页面所依赖的全部类实例。
由于Component,Module,整个app的类实例结构变的很清晰。安全

3.解耦

假如不用dagger2的话,一个类的new代码是很是可能充斥在app的多个类中的,假如该类的构造函数发生变化,那这些涉及到的类都得进行修改。设计模式中提倡把容易变化的部分封装起来。app

说了那么多概念,估计你们已经对dagger有了必定的了解,那开我们的使用吧,毕竟实战才是最有用的嘛框架

使用

仍是结合一开始的例子,咱们采用dagger的方式看如何给MainActivity 传递一个依赖的user对象maven

1.加入依赖包

Github-地址

// Add plugin https://bitbucket.org/hvisser/android-apt
buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }
}

// Apply plugin
apply plugin: 'com.neenbedankt.android-apt'

// Add Dagger dependencies
dependencies {
  compile 'com.google.dagger:dagger:2.x'
  apt 'com.google.dagger:dagger-compiler:2.x'
}复制代码

2.注解方法

  • @Inject: 一般在须要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段须要依赖注入。这样,Dagger就会构造一个这个类的实例并知足他们的依赖。

  • @Module: Modules类里面的方法专门提供依赖,因此咱们定义一个类,用 @Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到须要的 依赖。modules的一个重要特征是它们设计为分区并组合在一块儿(好比说,在咱们的app中能够有多个组成在一块儿的modules)。

  • @Provides: 在modules中,咱们定义的方法是用这个注解,以此来告诉Dagger咱们想要构造对象并提供这些依赖。

  • @Component: Components从根本上来讲就是一个注入器,也能够说是@Inject和@Module的桥梁,它的主要做用就是链接这两个部分。 Components能够提供全部定义了的类型的实例,好比:咱们必须用@Component注解一个接口而后列出全部的   @Modules组成该组件,如 果缺失了任何一块都会在编译的时候报错。全部的组件均可以经过它的modules知道依赖的范围。

  • @Scope: Scopes但是很是的有用,Dagger2能够经过自定义注解限定注解做用域。后面会演示一个例子,这是一个很是强大的特色,由于就如前面说的同样,不必让每一个对象都去了解如何管理他们的实例

能够粗滤的过一遍,估计看完也是一头雾水,仍是投入到实战中去认识吧!

3.初始user对象

和传统方法同样很少讲了,设置一些属性罢了

public class User {
    private String name;
    private String sex;
    private String ads;

    ******get/set**********
 }复制代码

4.生成对应module对象

module类就是给user初始化而且提供外部调用的类,这里类中咱们须要给user初始,而且返回给dagger一个可调用的对象

@Module
public class UserModule {

    @Provides
    User provideUser(){
        return new User("xxxx","SEX","XXX@Gmail.com");
    }
}复制代码

使用@Module标识类型为module,并用@Provides标识提供依赖的方法

5.生成Component对象

有了提供依赖的组件(module),咱们还须要将依赖注入到须要的对象中。链接提供依赖和消费依赖对象的组件被称为Injector。Dagger2中咱们将这个对象其称为component。UserComponent代码以下

@Component(modules = UserModule.class)
public interface UserComponent {
    void inject(MainActivity mainActivity);
}复制代码

能够看到,Component是一个使用@Component标识的Java interface。interface的inject方法须要一个消耗依赖的类型对象做为参数:经过 @Component 添加了一个 Module : UserModule,此外还有一个inject方法,其中的参数表示要注入的位置(先打个预防针,Component中的方法还能够起到暴露资源,实现Component中的“继承”的做用)

注意:这里必须是真正消耗依赖的类型MainActivity,而不能够写成其父类,好比Activity。由于Dagger2在编译时生成依赖注入的代码,会到inject方法的参数类型中寻找能够注入的对象,可是实际上这些对象存在于MainActivity,而不是Activity中。若是函数声明参数为Activity,Dagger2会认为没有须要注入的对象。当真正在MainActivity中建立Component实例进行注入时,会直接执行按照Activity做为参数生成的inject方法,致使全部注入都失败。(是的,我是掉进这个坑了。)

6.完成依赖注入

最后,咱们须要在MainActivity中构建Injector对象,经过dagger获得咱们的user对象

public class MainActivity extends AppCompatActivity {
    @Inject
    User user;
    UserComponent component;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        component= DaggerUserComponent.builder().userModule(new UserModule()).build();
        component.inject(this);
        TextView textView=(TextView)findViewById(R.id.tv);
        textView.setText("name:"+user.getName()+"\nsex:"+user.getSex()+"\nads:"+user.getAds());
    }
}复制代码

首先,使用@Inject标志被注入的对象User (注意User 不能为private),以后经过Dagger2生成的实现了咱们提供的UserComponent 接口类DaggerUserComponent建立component,调用其inject方法完成注入。

至此,咱们使用Dagger实现了最简单的依赖注入!

注意:这里的DaggerUserComponent不是咱们本身建立的,是dagger自动在build时(可手动make project)建立的,后边的userModule也是更具你在Component设置的module对象生成的方法-若是不成功需先clean工程在make一遍


效果

这里写图片描述


专栏

注解专栏


源码

源码传送门


建议

若是你有任何的问题和建议欢迎加入QQ群告诉我!

相关文章
相关标签/搜索