关于MVP+Dagger2的一些知识

原文地址://www.greatytc.com/p/01d3c014b0b1

看了大神Android-从零开始搭建android框架系列 前几章还比较清晰 到了dagger2发现了dagger2的优点 但是+mvp就不是特别理解如何在项目中运用。

文章评论中推荐了另一个作者的文章

地址 ://www.greatytc.com/p/65737ac39c44

需要找时间把这三篇文章看明白 然后再修改mvp模式的demo

笔记1.
依赖注入(Dependency Injection简称DI)
java中 注解(Annotation)

Inject
优点:取消new对象通过 注入 获取实例
注解(Annotation)来标注目标类中所依赖的其他类,同样用注解来标注所依赖的其他类的构造函数,那注解的名字就叫Inject

Component
一个连接两个类的桥梁
需要引用到目标类的实例,查找用Inject注解标注的属性,与对应的构造函数并赋值,Component也叫注入器(Injector)

Module
封装第三方类库使用,简单的工厂模式。

Component中的modules属性可以把Module加入Component,modules可以加入多个Module。

Provides
Module中的创建类实例方法用Provides进行标注,Component在搜索到目标类中用Inject注解标注的属性后,Component就会去Module中去查找用Provides标注的对应的创建类实例方法,这样就可以解决第三方类库用dagger2实现依赖注入了。

笔记2

Qualifier(限定符)
通过Inject创建实体类和通过Module创建实体类创建一个类时,依赖注入迷失,用限定符对不同创建实例方法标识,对目标类响应的实例属性进行标注,能解决问题。

Scope(作用域)
通过自定义Scope注解可以更好的管理创建的类实例的生命周期。

划分Component有两种,一种针对全局,最终针对activity或者fragment

Singleton
(在Module中定义创建全局类实例的方法
ApplicationComponent管理Module
保证ApplicationComponent只有一个实例)
更好的管理ApplicationComponent和Module之间的关系,保证ApplicationComponent和Module是匹配的。若ApplicationComponent和Module的Scope是不一样的,则在编译时报错。

组织Component
类实例共享三种方式
依赖方式:Component中的dependencies属性
包含方式:SubComponent就是包含方式的具体实现
继承方式:把一些Component共有的方法抽象到一个父类中,然后子Component继承

Scope
更好的管理Component之间的组织方式,更好的管理Component与Module之间的匹配关系,可读性提高,如用Singleton标注全局类,这样让程序猿立马就能明白这类是全局单例类。

笔记3

dagger2的好处
增加开发效率,省去重复的简单体力劳动。
更好的管理类实例。
解耦

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

`

注意事项
1.一个app必须要有一个Component(名字可以是ApplicationComponent)用来管理app的整个全局类实例
2.多个页面可以共享一个Component
3.不是说Component就一定要对应一个或多个Module,Component也可以不包含Module
4.自定义Scope注解最好使用上,虽然不使用也是可以让项目运行起来的,但是加上好处多多。

接下来分析一下大神的Demo

原地址:https://github.com/niuxiaowei/Dagger2Sample

首先看一下项目结构


结构1.png
结构2.png

这里边有个有趣的事情
App这个类中DaggerAppComponent 是报错的 没有找到这类,但是项目编译后已经导入不报错了,点开文件发现文件在debug文件夹内


结构3.png

这个文件位置在上边,这种情况我是没有用到过的,发现这个类被 @Generated 标记了,也许和这个标注有关。

Demo运行起来很简单 两个按钮 一个获取用户信息,一个点击显示toast

首先分析一下data包
GetUserData构造方法被 @Inject标注了,其中还有getUser()方法,返回的是一个UserData的实例,name属性有值。
UserData是一个实体类只有一个name属性。

di包就是dagger2用到相关的类

components包连接两个类的桥梁
ActivityComponent 是同时被Component和scopes.PerActivity标注的里边有一个getActivity()方法。
AppComponent有两个标记@Singleton是单例的意思,@Component是连接器的意思,里边有3个方法,获取上下文,获取toast工具,获取Navigator。
MainComponent有两个标记@PerActivity和@Component并继承了ActivityComponent。里边有两个方法inject(mainActivity)方法和获取mainFragmentComponent实例的方法。
MainFragmentComponent类中有两个标记@PerActivity和@Subcomponent,还有一个inject(mainFragment)方法。

modules封装第三方类库使用,简单的工厂模式。
AppModule被@Module标记,里边有个三个方法provideContext,provideNavigator,provideToastUtil都被 @Provides 和@Singleton标记。
ActivityModule也被@Module标记,在构造方法中传入了activity实例,并通过被@Provides 和 @PerActivity 标记的provideActivity方法return出去。
MainModule也被@Module标记,里边只有1个@Provides标记的provideUserData()方法

scopes作用域包只有被@Scope和@Retention标记的PerActivity接口。

presenter包下只有MainPresenter这个类,里边有一个静态接口IUserView和它的set方法与实例。它的构造方法被@Inject标记并传入了GetUserData的实例,通过getUser方法给接口传递了数据

view包下 BaseActivity 有1个getAppComponent方法,BaseFragment没有方法。
MainActivity实现了MainFragment中的一个监听接口,通过DaggerMainComponent.builder()方法获取了ActivityModule的对象并调用了inject方法,提供了getMainComponent方法 return这个对象。
mainFragment这个类中通过@Inject 获取了mainPresenter、toastUtil、multiConstruct三个实例在onActivityCreated方法中得到MainFragmentComponent对象并实现inject方法,通过mainPresenter的setUserView 设置了数据,在onCreateView的两个点击事件中通过mainPresenter获取了数据,通过toastUtil展示了toast.

在包的最外层App的onCreate中获取了AppModule对象并提供了return方法。
MultiConstruct类中 @Inject了构造函数
Navigator被@Singleton标记了。
ToastUtil封装了展示吐司的方法。

总结一下:
di包的components包中都是注入器,有app注入器、activity注入器、main注入器、fragment注入器。main注入器继承了activity注入器,对MainActivity进行依赖注入。
Module是一个提供类实例的类,通过标注关联了2个实例MainModule和ActivityModule,加入main注入器,他们的方法都被@Provides标注了。
当module中的类需要创建实例的时候需要用@PerActivity标记出来。
MainComponent继承了ActivityComponent并采用dependencies标记依赖了 AppComponent。
MainFragmentComponent通过@PerActivity与MainComponent声明了相同的作用域并通过@Subcomponent声明被包含的。

工厂模式也可以降低耦合度。
依赖注入:从容器中查找合适的对象,对当前的对象进行赋值。
被@Component标注类为注入器,bean生成工厂类,运行后在apt-debug包下。
注入器不能直接new 只能通过创建器进行创建。

@Inject只能针对无参构造,可以修改源代码。

@Module与@Provides 针对有参构造和jar包使用。对工厂模式类进行@Module,对实例类@Provides 方法用Provides 开头。在component类中标注出module的类,inject方法查找界面@inject的类进行赋值。调用时需多指定创建实例的工厂。

获取注入器 需要编译 生成dagger开头的类

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,825评论 25 707
  • 时间是个大话题,和它有关的或喜或悲。于我而言却是多悲。 临近过年感想也会比平常来的多,父亲每日为生计奔...
    54e1682bf952阅读 557评论 0 0
  • 下午见到我的学生们,感觉自己亲和力更强了。表扬鼓励他们的话那么自然,他们也都笑得好开心 我爱孩子们,理性上接纳他们...
    吾书吾心阅读 76评论 0 0
  • 不喜欢忧思过重的我, 总是让自己夜里失眠。 即使笑的时候, 也不忘提醒自己, 人生不会总是圆满; 不喜欢胆怯含蓄的...
    平安喜乐岁月静好阅读 374评论 1 2