android系统框架之Dagger2

前:最近Darrger2+MVP+Retrofit+Rx系列构建的系统框架模式好像还挺热,这些框架在之前做的开发中都选用过。准备花一些时间系统的从各个的使用Demo到联合搭建成一个应用的框架,本篇是这一系列的第一篇view层的Dagger2的使用。

目录


一句话总结

Dagger2是google开发和维护的采用依赖注入模式进行view层解耦的框架。

gitHub:https://github.com/google/dagger

android在bulid.gradle里加上(需要使用APT插件)

dependencies {

compile ‘com.google.dagger:dagger:2.4’
apt ‘com.google.dagger:dagger-compiler:2.4’
//java注解
compile ‘org.glassfish:javax.annotation:10.0-b28’

}

APT插件需要
bulid.gradle(Modle:app)内

apply plugin: ‘com.neenbedankt.android-apt’

bulid.gradle(Project:xxx)内

dependencies {
*
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
}

Dagger2基本使用简介

Dagger2注解简介

 Dagger2是基于Java注解来实现依赖注入的,那么在正式使用之前我们需要先了解下Dagger2中的注解。Dagger2使用过程中我们通常接触到的注解主要包括:@Inject, @Module, @Provides, @Component, @Qulifier, @Scope, @Singleten。

-@Inject 顾名思义 就是注入的意思 ,有两个作用1:标记需要被注入的变量;2:标记构造函数,即为需要被注入的变量提供相关事例(有点拗口。。。)

-@Module 模版用于标记提供注入的类,用于补充@Inject所不能使用的地方。

-@Provides 用于标记已经标记过@Module类中的方法,类似只提供相应的方法接口出去给别的类调用的这种方式

-@Component 用于标注接口 是标注的依赖类和标注的注入类的桥接类(类似MVP中的P层),被此接口标注的接口会在编译的时候生成实现类,注入类通过调用此实现类来注入

-@Qulifier 用于自定义注解。用于解决当多个被@Module注解的类中有若干个(>1)个标注@Provides的方法时,用于分他们

-@Scope 用于自定义注解,限注解的作用域,局部单例

-@Singleten用于自定义注解,单例(准确是说在Component 作用域内的单例,一般是全局单例)

示例

@inject+@Component (无参构造)

简单的写一个人吃饭的示例
首先有个Hand类代表手

public class Hand {
    @Inject
    Hand(){}

    public  void eat(){

        System.out.println("人吃东西");
    }

}

在Hand类的无参构造函数上加@Inject注解表明这个为提供依赖类,之后创建People类通过@Inject将Hand类作为参数注解进来(此时DaggerPeopleComponent还没有被创建 所以还不能用)


public class People  {

    @Inject
    Public Hand mHand;

    public People() {
    //(此时还不能用,需要编译一下)
      DaggerPeopleComponent.builder().build().inject(this);

    }


}

之后需要一个接口类来管理依赖类与注入类(可提供多个)

@Component

public interface PeopleComponent {

    void inject(People people);
}

此时,重新编译一个项目 这样DaggerPeopleComponent就会被创建出来

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class DaggerPeopleComponent implements PeopleComponent {
  private MembersInjector<People> peopleMembersInjector;

  private DaggerPeopleComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {
    return new Builder();
  }

  public static PeopleComponent create() {
    return builder().build();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {

    this.peopleMembersInjector = People_MembersInjector.create(Hand_Factory.create());
  }

  @Override
  public void inject(People people) {
    peopleMembersInjector.injectMembers(people);
  }

  public static final class Builder {
    private Builder() {}

    public PeopleComponent build() {
      return new DaggerPeopleComponent(this);
    }
  }
}

看以下Dagger2帮我们创建的实现类,就是建造者模式+java中的注入。并不是很难看懂。此时People类中的DaggerPeopleComponent.builder().build().inject(this);就可以使用了。
之后在people类中就可以直接调用mHand的eat方法了people.mHand.eat();
输出结果System.out: 人吃东西

有参构造或不能修改

首先Hand类是有参的构造函数或者不能修改Hand类

public class Hand {
    String type;

    Hand(String type) {
        this.type = type;
    }

    public void eat() {

        System.out.println(type+"人吃东西");
    }

}
情况类似。只为说明不能将注解添加到此class上)

接着需要一个Module类用来对Hand类进行扩展(@Module+@Provides)

@Module
public class HandModule {
    public HandModule(String type) {
        this.type = type;
    }

    String type;
    public  HandModule(){}

    @Provides
    Hand ProvidesGetHand(){
        return  new Hand(type);
    }
}

对Component的这个接口进行限制

@Component(modules = HandModule.class)

public interface PeopleComponent {

    void inject(People people);
}

还差一个people类

public class People  {

    @Inject
    public Hand mHand;

    public People() {
//        DaggerPeopleComponent.builder().build().inject(this);
            DaggerPeopleComponent.builder().HandParams(new HandModule("中国")).build().inject(this);
    }

}

重新编译以下后就可以使用了。
输出结果System.out: 中国人吃东西

多个Module

当有多个Module时需要使用@Qulifier进行区分
首先要有两个注解类

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface QulifierChinese {
}
和
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface QulifierForeigner {
}

Module 需要在你调用的方法上面加入相应的注解 这样就保证了调用的唯一性,也去掉了不同module下相同方法名不能识别的问题。因为返回结果根据你添加的注解头确定。

@Module
public class HandModule {

    public HandModule(String type,String code) {
        this.type = type;
        this.code = code;
    }
    String code;
    String type;
    public  HandModule(){}

    @QulifierChinese
    @Provides
    Hand ProvidesGetHandChinese(){
        return  new Hand(type);
    }

    @QulifierForeigner
    @Provides
    Hand ProvidesGetHandForeigner(){
        return  new Hand(code);
    }
}

@Component那边不需要修改.Peolpe类中需要根据你使用的方法添加特定的注解头

public class People  {
    @QulifierChinese @Inject public Hand mHandChinese;
    @QulifierForeigner @Inject public Hand mHandForeigner;

    public People() {
//        DaggerPeopleComponent.builder().build().inject(this);
        DaggerPeopleComponent.builder().handModule(new HandModule("中国","外国")).build().inject(this);
    }

}

输出结果System.out: 中国人吃东西/System.out: 外国人吃东西 输入根据你调用的方法

单例注解

首先需要一个注解类

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface HandScope {
}

接着需要使用@Scope注解分别标注 Module和@Compentent注解类。代码就不贴了就加了两个标注头 @HandScope

小结

以上就是Dagger2的基本用法,不过dagger2常用与跟MVP结合在一起,下一篇将与mvp结合在一起展示实际用法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值