热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

Dagger2依赖注入前面我们做好学习准备接下来就要研究如何使用了,俗话说的好,一个东西需要先会用,然后才更好的学习原理。一、导入Dagger2在工程的build.gradle文件中添

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 provideBoyProvider;

private Provider provideParentsProvider;

private MembersInjector 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;
}
}
}

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


推荐阅读
author-avatar
韦小娇900_433
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有