android开源库---Dagger2入门学习(简单使用)

Dagger2依赖注入

前面我们做好学习准备接下来就要研究如何使用了,俗话说的好,一个东西需要先会用,然后才更好的学习原理。

一、导入Dagger2

在工程的build.gradle文件中添加android-apt插件(该插件后面介绍)

buildscript {

    ....

    dependencies {

        classpath 'com.android.tools.build:gradle:2.1.0'
        // 添加android-apt 插件
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

在app的中的build.gradle文件中添加配置

apply plugin: 'com.android.application'
// 应用插件
apply plugin: 'com.neenbedankt.android-apt'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.mahao.alex.architecture"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'

    // dagger 2 的配置
    compile 'com.google.dagger:dagger:2.4'
    apt 'com.google.dagger:dagger-compiler:2.4'
    compile 'org.glassfish:javax.annotation:10.0-b28'// 添加java 注解库
}

android-apt是Gradle编译器的插件,根据其官方文档,主要两个目的:

  • 编译时使用该工具,最终打包时不会将该插件打入到apk中。
  • 能够根据设置的源路径,在编译时期生成相应代码。

二、写个Demo

这个就依照上篇的女孩依赖于一个男孩,这我们再加一个依赖就是父母(毕竟男人不一定靠的住^(* ̄(oo) ̄)^)。好了开始写
写一个Module类,管理上面的依赖。

@Module
public class GirlModule {
    @Provides
    public Boy provideBoy(){
        return new Boy();
    }

    @Provides
    public Parents provideParents(){
        return new Parents();
    }

}

写一个Component类,来连接Module和你的Girl。

@Component(modules = GirlModule.class)
public interface GirlComponent {
    void inject(Girl girl);
}

到了这里不要急着往下写,先运行一下你的代码。(下面再说为什么)

好了,继续下一步,重写Girl类

public class Girl {
    @Inject
    Boy boy;
    @Inject
    Parents parents;
    public Girl() {
        DaggerGirlComponent
                .builder()
                .girlModule(new GirlModule())
                .build()
                .inject(this);
        Log.d("Girl", "new Girl()");

    }

}

首先我们可以看到在使用过程出现了很多注解:

  • @Module:作为实例对象的容器。
  • @Provides:标注能够提供实例化对象的方法。
  • @Component:作为桥梁,注入对象的通道。
  • @Inject:需要注入的方法

分析

我们可以看到在GirlModule 是用一个@Module注解的类,这是作为实例对象的容器,用于管理,里面的方法是使用@Provides注解,可以看出来其实就是给你提供依赖的方法。
我们知道了管理并提供依赖的类,那么我们就可以通过它来直接使用依赖。但是Dagger2为了解耦,提供了一个中介,@Component注解,这是作为桥梁将依赖和需求(girl)联系起来。


@Component(modules = GirlModule.class)
public interface GirlComponent {
    void inject(Girl girl);
}

那么我们来看看@Component的官方文档。

* Annotates an interface or abstract class for which a fully-formed,     dependency-injected
 * implementation is to be generated from a set of {@linkplain #modules}.

说的是这个注解只能用于接口或者抽象类。将代码改成下面,输出也是一样的。

@Component(modules = GirlModule.class)
public abstract GirlComponent {
    void inject(Girl girl);
}

还有 @Inject注解 就是使用的时候的注入方法。

 @Inject
    Boy boy;

上面的代码表示Boy 这个属性你不用像一般情况去初始化(boy= new Boy ()),它能给你自动寻找依赖。
但是这样就可以了么?当然是不行,你都没有和前面的联系其来。所以还需要如下代码:

DaggerGirlComponent
                .builder()
                .girlModule(new GirlModule())
                .build()
                .inject(this);

这里你就会看到一个你没有创建的类是,这个是由apt工具帮我们生成的类,但是是在编译时期生成代码,所以为什么前面要你们先运行下(我之前就是一头雾水,大部分人都说生成没说怎么生成,搞的我一度误解)

这里tip一下


在android-apt的文档中,也推荐使用这种方式。因为,编译时期生成代码的类库在运行期并不需要,那么将其分为两个库,(运行类库dagger)和(编译器生成代码类库(dagger-compiler)),那么在打包时,就不需要将dagger-compiler打入其中(用不到),减小APK 的大小。


DaggerGirlComponent实现了GirlComponent接口。
通过girlModule()将我们的依赖提供者传入,通过inject()将我们的Girl对象传入,这样就达到了中间人的目的。

package com.example.admin.dagger2.gg;

import dagger.MembersInjector;
import dagger.internal.Preconditions;
import javax.annotation.Generated;
import javax.inject.Provider;

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class DaggerGirlComponent implements GirlComponent {
  private Provider<Boy> provideBoyProvider;

  private Provider<Parents> provideParentsProvider;

  private MembersInjector<Girl> girlMembersInjector;

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

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

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

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

    this.provideBoyProvider = GirlModule_ProvideBoyFactory.create(builder.girlModule);

    this.provideParentsProvider = GirlModule_ProvideParentsFactory.create(builder.girlModule);

    this.girlMembersInjector =
        Girl_MembersInjector.create(provideBoyProvider, provideParentsProvider);
  }

  @Override
  public void inject(Girl girl) {
    girlMembersInjector.injectMembers(girl);
  }

  public static final class Builder {
    private GirlModule girlModule;

    private Builder() {}

    public GirlComponent build() {
      if (girlModule == null) {
        this.girlModule = new GirlModule();
      }
      return new DaggerGirlComponent(this);
    }

    public Builder girlModule(GirlModule girlModule) {
      this.girlModule = Preconditions.checkNotNull(girlModule);
      return this;
    }
  }
}

到这里基本的入门使用就知道。
这里想必还是一头雾水感觉不出有什么用处,不要着急,饭要一口一口吃,我们先了解使用,然后再慢慢一步一步了解。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值