书接上文,先回顾以下前一章写的内容。

内容大概就是在Activity中用@Inject标记一个注入的类,然后在这个类的构造函数上也打个@Inject标记,然后使用@Component来连接两边,完成对象的创建和注入。整体流程朴实无华,且枯燥。

到这里可能就有花生发现了西瓜!

如果要注入的是第三方库呢?我不可能去把封装好的第三方库打开,然后给它的构造函数打个@Inject!

那么我们就要引入四大基本组件的后两个组件:@Module和@Provide。

这两个是配套使用的,我直接在上一章的代码上改:

先新建一个FirstModule类:

@Module
public class FirstModule { @Provides
Tools provideTools(){
return new Tools();
}
}

@Provide标记的方法就是提供依赖的方法,一般方法名写成provide+类名。

约定俗成,约定俗成!理解万岁,李姐万岁!

然后在FirstComponent里面加上依赖

@Component(modules = FirstModule.class)//绑定Module
public interface FirstComponent { void inject(FirstActivity activity); }

为什么上一章我强烈不建议使用create()代替builder().build()呢?

原因就在这里,如果添加了Module就不能使用create()了,必须改回去。

将Activity中的注入语句也要更改:

DaggerFirstComponent.builder()
.firstModule(new FirstModule())//添加Module
.build()
.inject(this);

添加的代码如果标红了,就证明你没有编译,生成的DaggerFirstComponent中没有这个firstModule()方法。

上面代码很简单,把原来应该标记在class里构造函数的标记,移到了@Module里,@Module就像个包装盒,这个我们后面再讲。

先跑一下,看AS又给我们生成了什么有趣的东西。

老规矩,按逻辑来,先看DaggerFirstComponent.java

 public final class DaggerFirstComponent implements FirstComponent {
private Provider<Tools> provideToolsProvider; private MembersInjector<FirstActivity> firstActivityMembersInjector; private DaggerFirstComponent(Builder builder) {
assert builder != null;
initialize(builder);
} public static Builder builder() {
return new Builder();
} public static FirstComponent create() {
return builder().build();
} @SuppressWarnings("unchecked")
private void initialize(final Builder builder) { this.provideToolsProvider = FirstModule_ProvideToolsFactory.create(builder.firstModule); this.firstActivityMembersInjector = FirstActivity_MembersInjector.create(provideToolsProvider);
} @Override
public void inject(FirstActivity activity) {
firstActivityMembersInjector.injectMembers(activity);
} public static final class Builder {
private FirstModule firstModule; private Builder() {} public FirstComponent build() {
if (firstModule == null) {
this.firstModule = new FirstModule();
}
return new DaggerFirstComponent(this);
} public Builder firstModule(FirstModule firstModule) {
this.firstModule = Preconditions.checkNotNull(firstModule);
return this;
}
}
}

很长,先不看,待会儿有需要再回来翻。

先是builder(),建造者模式,没啥变化。但是Builder类中多了个方法,也就是前面提到的firstModule():

    public Builder firstModule(FirstModule firstModule) {
this.firstModule = Preconditions.checkNotNull(firstModule);
return this;
}

其实也没干啥,就在Builder中存了个Module的实例,我们Module中就一个provide方法,返回一个new Tools()。

这里有个checkNotNull,很好理解,就不多说了。

然后build(),又对DaggerFirstComponent进行初始化。(我为什么要说又?)

看起来是老调重弹,但我们又确确实实在里面找到了不一样的东西,看看initialize方法中的代码

this.provideToolsProvider = FirstModule_ProvideToolsFactory.create(builder.firstModule);

this.firstActivityMembersInjector = FirstActivity_MembersInjector.create(provideToolsProvider);

这个工厂类和之前的不一样了,FirstModule_ProvideToolsFactory。

看到个很熟悉的单词:Provide。没错,这个新的工厂类就是@Module和@Provide组合形成的新工厂类。

看看这个新工厂类的代码:

public final class FirstModule_ProvideToolsFactory implements Factory<Tools> {
private final FirstModule module; public FirstModule_ProvideToolsFactory(FirstModule module) {
assert module != null;
this.module = module;
} @Override
public Tools get() {
return Preconditions.checkNotNull(
module.provideTools(), "Cannot return null from a non-@Nullable @Provides method");
} public static Factory<Tools> create(FirstModule module) {
return new FirstModule_ProvideToolsFactory(module);
}
}

大失所望,代码还没名字长。

create()方法传进去一个module实例,然后把实例保存下来。需要get()时,就调用module.providTools()。

这个工厂类和之前的工厂类唯一区别就是create()方法多传了个module实例,用来调用provide方法。

绕了一圈,和前一章的方法又重合了。

相信认真看第一章的小伙伴都知道后面会发生啥。

等我会,我去上一章复制点文字来。

......

5、调用DaggerFirstComponent方法将工厂类的实例和Activity的实例都交给MemberInjecter

6、MemberInjecter组装完成,依赖成功注入。

是不是很眼熟?其实也没多难。

看完这四大组件的介绍,相信你对Dagger2已经有了基本的认识。

我们再来形象化的描述一下依赖注入的过程。

要给Activity进行依赖注入,最重要的就是要new一个指定对象赋值给Activity中用@Inject标记的那个声明。

其实就跟淘宝买东西一样,你在Activity中的声明就是下单,这里需要一个对象,请给我快递送过来。(那么问题来了,你的对象呢?)

对象哪里来呢?

工厂类。

至于是@Inject工厂还是@Provide工厂?都可以,会做蛋炒饭就行。

唯一不同的是,@provide工厂发出来的快递有个快递箱@Module装着。

我看的很多博客喜欢在@Module中给定个成员变量FirstActivity,美其名曰给快递盒上写上地址。

可不可以呢?可以。

有没有必要呢?看情况,个人观点,不调用,就没必要。

因为@Component这个快递员知道地址,你写不写,不重要。如果是要寄两家的快递,岂不是还要写两个地址?

但这里要注意个坑,前面我们都把@Module和@Component绑定了,一个@Component可以绑定多个@Module,但是多个@Module中提供的方法不能相同(其实可以,需要点小技巧)。但这还不是我要说的坑。

如果@Inject和@Provide同时存在,总有个优先级...吧?(我没有连读!)

华生们,我前面删Tools类里的@Inject了吗?      谁优先级高不言而喻。

流程是这样的,@Component会先去找绑定的@Module和@provide,没有才去找@Inject。

如果绑定的@Module中有@Provide()方法,但是你注入时没有调用firstModule()这个方法,会报错。

基本源代码就分析到这,相比大家对Dagger2也有了基本了解,下面我就来讲讲稍微复杂点的用法。

还是下章吧........

Dagger2 探索记2——四大基本组件(二)的更多相关文章

  1. Dagger2 探索记1——四大基本组件(一)

    喝很多自主学习的人,我接触Dagger 2 框架的原因是刚进公司的时候导师给安排的学习任务,学习方式是组内培训. 听到这个消息的我,以为是部门的人轮流给我讲课. 后来导师跟我说,组内培训的意思是,我先 ...

  2. Dagger2 探索记3——两大进阶组件(一)

    今天要讲的时@Scope这个组件.为什么说它是进阶组件,就是因为它基本上没作用,但在理解了基本组件之后又必须用到. Scope的意思是作用域,一般用来标记@Provide方法,将生成的对象单例化.但@ ...

  3. Android四大基本组件介绍与生命周期

    Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器 ...

  4. 17.(转) Android之四大基本组件介绍与生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity ...

  5. Android基础_1 四大基本组件介绍与生命周期

    Android四大基本组件分别是Activity,Service(服务),Content Provider(内容提供者),BroadcastReceiver(广播接收器). 一.四大基本组件 Acti ...

  6. 【转】Android四大基本组件介绍与生命周期

    转自:http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html Android四大基本组件分别是Activity,Serv ...

  7. android拾遗——四大基本组件介绍与生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity ...

  8. Android四大基本组件介绍及生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一.了解四大基本组件 Activity ...

  9. Android四大基本组件

    Android四大基本组件分别是 Activity:整个应用程序的门面,负责与用户进行交互. Service:承担大部分工作. Content Provider内容提供者:负责对外提供数据,并允许需要 ...

随机推荐

  1. XILINX FPGA 开发板 XC3S250E 核心板 学习板+12模块

    北京太速科技有限公司为广大合作单位特设海外代购业务,主要包括各类板卡.相机.传感器.仪器仪表.专用芯片等.代购业务仅收取基本的手续费. 北京太速科技有限公司在线客服:QQ:448468544 淘宝网站 ...

  2. 141-FMC141-4路 250Msps/16bits ADC, FMC板卡

    FMC141-4路 250Msps/16bits ADC, FMC板卡 一.产品概述: 本板卡基于 FMC 标准板卡,实现 4 路 16-bit/250Msps ADC 功能.遵循 VITA 57 标 ...

  3. spring cloud学习笔记二 ribbon负载均衡

    Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为.为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求.Ribb ...

  4. vue-ivew input 框 回车搜索功能

    1. 添加事件 <FormItem prop="> <Input type="text" v-model="formInline.produc ...

  5. logging error. UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

    根据错误提示, 找到出错的文件. 可以看到, 出错的文件是 logging 模块中的__init__.py 文件. 根据目录, 找到 这个文件, 并打开它 搜查这个文件的内容, 找'encoding' ...

  6. sql中强制使用索引

    如果在sql中使用的索引不生效,可以使用FORCE INDEX(索引),来强制使用索引: 例: SELECT COUNT(DEAL_STAT) FROM  c_pac FORCE INDEX (IDX ...

  7. Python3 使用HTMLTestRunner.py 报错ImportError: No module named 'StringIO'处理方法

    HTMLTestRunner.py文件是基于Python2的语法,python3使用需要修改语法: 1.>>> 94行 import io # import StringIO 2.& ...

  8. windows系统的安装时间怎么查看

    方法一:利用命令符窗口查询 直接按下Windows+R组合键  出现运行对话框(或 点击开始—运行),输入cmd,进入命令符窗口 然后,在该界面下输入”systeminfo”,然后回车,等待系统自动运 ...

  9. 【靶场练习_sqli-labs】SQLi-LABS Page-3 (Stacked Injections)

    Less-39: ?id=1 and 1 ,?id=1 and 1 : 回显不同,数字型 ?id=0 union select 1,2,group_concat(table_name) from in ...

  10. jQuery 问题收集

    1.页面动态生成的dom元素,监听事件失效.需用事件代理进行监听. 对于动态绑定元素可以这样写 $(document).on('click', '.xxx', function() { // do s ...