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

Dagger2使用正确姿势。

Dagger2使用正确姿势。上一篇文章《[Dagger2这次入门就不用放弃了](http:blog.csdn.netu012943767articledetails51

Dagger2 使用正确姿势。

上一篇文章《[Dagger2 这次入门就不用放弃了](http://blog.csdn.net/u012943767/article/details/51897247》中介绍了Dagger2的一些显浅的使用方式,我觉得是非常适合入门Dagger2的傻瓜式讲解,后来发现有些内容讲的不够仔细,有些细节没有详细解释清楚。参考了以下三篇文章后,对之前的内容进行一些补充。

  • Android:dagger2让你爱不释手-基础依赖注入框架篇
  • Android:dagger2让你爱不释手-重点概念讲解、融合篇
  • Android:dagger2让你爱不释手-终结篇

以上这三篇文章对于Dagger2的思路理得很清晰,并且对于Dagger2做出了一个抽象的概念讲解,本文的一些内容也是摘自以上文章。

没有看过《Dagger2 这次入门就不用放弃了》可能不利于阅读

本文的内容:

本篇的内容同样不涉及到Dagger2的内部原理,只是对上一篇文章做了一些知识的补充,从而能够更好的使用Dagger2

  • 理清思路,Dagger2的两种提供注入实例的方式
  • 为什么ActivityComponent要提供一个inject方法。
  • Scope的使用,如何实现单例?
  • Qualifier限定符的作用以及使用。
理清思路,Dagger2的两种提供注入实例的方式。

之前说的是提供注入实例的方式是通过编写Moudle,并且提供一些provideXXX()的方法,然后通过Component把这些对象进行注入。
其实在Dagger2中还有一种方式实现对象的注入,这种方式比较简单。假设我们需要注入一个A类的对象,我们只需要在A类的构造函数中添加@Inject注解即可,然后在Component中直接提供一个方法获取A的实例就行了。代码如下:


public class A{

@Inject
public A(){
}
}


//在 XXXComponent 中

A getA();

然后在我们需要注入A对象的地方(Activity),使用Component调用getA()方法即可获得这个A对象。

说到这里,可能也会有些疑问,这里的A类是一个简单的对象,假如A需要在构造函数传入参数怎么办?其实原理和上一篇文章说的差不多,这些参数会根据依赖的Component或者当前Componentmodule中提供的provideXXX()方法来获取。

这里的Dagger2总共就有这两种方式提供依赖的注入。事实上,经过测试,Dagger2在遇到@Inject修饰的成员变量的时候,会先查找Component中是否有提供对象,找不到的情况下,才会去找包含有@Inject的构造函数。

整个Dagger2的依赖注入的过程如下:

步骤1:查找Module中是否存在创建该类的方法。
步骤2:若存在创建类方法,查看该方法是否存在参数
步骤2.1:若存在参数,则按从**步骤1**开始依次初始化每个参数
步骤2.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
步骤3:若不存在创建类方法,则查找Inject注解的构造函数,
看构造函数是否存在参数
步骤3.1:若存在参数,则从**步骤1**开始依次初始化每个参数
步骤3.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
为什么ActivityComponent要提供一个inject方法

首先经过我的测试,当我在DaggerActivity中对对某些需要注入的成员添加@Inject注解的时候,Dagger2就会生成一个DaggerActivity_MembersInjector的东西,这个是对成员变量进行注入的关键类,涉及到一些比较深入的内容,我们这里先不要深入探讨这里的运行机制。我们只需要知道当我们需要注入一些成员变量的时候,我们需要在ActivityComponent中提供一个方法:

void inject(DaggerActivity daggerActivity);

并且在初始化的时候调用这个方法,才能成功注入。至于这个方法inject是官方推荐的名称,我们可以不用这个,但是使用inject的话比较好理解吧。值得注意的一点是,这个方法的参数一定要准确,比如DaggerActivity需要注入,我们这里就需要些DaggerActivity,不能写成BaseActvity或者Activity,否则会注入失败。因为内部的原理是要对这个参数进行注入的,很显然在DaggerActivity中需要注入的内容在BaseActivity或者Activity中并不存在。

Scope的使用,如何实现单例?

这个迷之Scope也是有点难以理解,我们在哪里使用到了Scope呢。在我们的AppComponent中添加了一个注解为@Singleton@Singleton就是一个Scope,据说可以实现单例哟。。。难道这样就实现了单例模式?我刚刚开始是这样理解的。直到仔细的看了几遍这篇文章我才知道并不是这样的。

事实上@Sinleton中并没有创建单例的能力,那么AppComponent中提供的依赖注入是如何实现单例的呢。其实这个原理很贱单。

首先Module提供了创建实例的方法,接着AppComponent中对Module进行管理,最后AppComponent在自定义Applicaiton中被实例化了一次

这个实例化了一次是最重要的呀。仅仅被实例化了一次,那不就是单例么。就是这么简单呀。

可能有些童靴当时就不乐意了,那既然这样都已经实现了单例,那么这个@Singltop还要来何用?不是多此一举吗。

其实@Singletop还有有一些作用的,首先一方面能让你直面的了解到这是一个单例,其次这个@Singletop能够更好的管理ModlueComponent之间的关系。

Dagger2需要保证ComponentModule是匹配的,就需要用到这个注解。

为什么这样说,看过上一篇文章的人就会知道,我定义了一个ActivityScope,我之前的解释是说ActivityScope是为了对应Activity的生命周期(当时就很不理解,难道这个Scope真的这么有魔性,声明一个ActivityScope就能让提供的注入对象和Activity生命周期一致),很显然,这是错误的。为什么需要这个Scope呢?原因是因为我在AppComponent中是有@Singletop的,ActivityComponent中依赖了AppComponent,所以我们需要使用一个Scope来匹配他们之间的关系,不然就会在编译期间报错。并不是说ActivityScope能让实例和Activity生命周期一致。和Activity生命周期一致是因为ActivityComponent是在Activity中生成实例的。(具体Dagger2内部是如何保障这个的,并没有深入研究过)。

Qualifier 限定符的作用以及使用。

这也是一个很强大的注解,首先为什么需要用这么一个东西呢,之前说道过,在Module中的provide方法实际上是根据返回值来进行识别的。但是假设我需要根据不同的需求传入不同的构造参数的时候,如何区分呢?比如:一个Presenter,可能他有两个构造函数,分别对应不同的需求,这种情况下,provide方法的返回值都是Presenter,那么就需要使用Qualifier。具体怎么使用呢。

首先声明一个注解用@Qualifier修饰,然后在需要区别的地方添加就行了,下面是一个实例代码:

@Module
public class AppModule {
private final App app;

public AppModule(App app) {
this.app = app;
}

@Provides
@Singleton
@ForApplication
Context provideAppContext() {
return app;
}

@Provides
@Singleton
Prefser providePrefser(@ForApplication Context context) {
return new Prefser(context);
}

@Provides
@Singleton
AccountManager provideAccountManager(@ForApplication Context context) {
return AccountManager.get(context);
}

首先在provide中添加一个注解@ForApplicition,接着在需要使用这个Context的地方再次标示即可。这样假设有其他一些提供了ActivityContext的地方和这里发生冲突的时候,Dagger2也能准确找到这个ApplicaitonContext

总结

这里对Dagger的总体使用方式进行了一些补充,还有没有从源码的角度来理解Dagger2,下篇文章会结合Dagger2生成的代码进行讨论,只有认识了这个运行机制,我们才能运用得得心应手。


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
author-avatar
王文波玉龙_946
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有