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

dagger2简单使用与理解笔记

文章目录使用dagger2好处具体案例查看github1.使用dagger2注入基本使用流程概念2.dagger2中各种注解基本使用引入dagger20.写两个对象用来实际操作的1


文章目录

  • 使用dagger2好处
    • 具体案例查看github
  • 1. 使用dagger2注入基本使用流程
    • 概念
  • 2. dagger2中各种注解基本使用
      • 引入dagger2
      • 0. 写两个对象 用来实际操作的
      • 1. 写module类 (注解Module). Provides方法提供对象(Provides注解).
      • 2. Component 创建
      • 3. 在activity里面注入并调用
        • 打印结果
      • 4. 单例使用
        • 局部单例
          • model类
          • Component组件
          • 注入使用
        • 打印结果
        • 全局单例
      • 5. 多个Component组合依赖
        • 作用域@Scope
          • 使用Scope 注意两点
      • 6. 组合的其他用法
  • 3. dagger注入原理源码分析
      • 实际上是通过apt技术生成了代码


使用dagger2好处


  1. 解耦.比如需要更换http的框架, 只需要在HttpModule 中更换提供者的对象即可
  2. 把对象给dagger2管理 更好的管理类实例
  3. 增加开发效率、省去重复的简单体力劳动 避免不断的去new对象

具体案例查看github

https://github.com/liudao01/IOCProject


1. 使用dagger2注入基本使用流程


  1. IOC(Inversion of Control):控制反转
    在Java开发中。IOC是原来由程序代码中主动获取资源的方式,转变为由第三方获取资源并使原来的代码被动接收资源的方式,以达到解耦的效果,称为控制反转。

概念


2. dagger2中各种注解基本使用


引入dagger2

implementation 'com.google.dagger:dagger:2.35'annotationProcessor 'com.google.dagger:dagger-compiler:2.35'//APT注解处理器技术, 利用APT生成代码

0. 写两个对象 用来实际操作的


/*** Created by liuml on 2022/4/14 10:47*/
public class HttpObject {String TAG = "HttpObject";public void post() {Log.d(TAG, "HttpObject post: post请求数据 ");}
} /*** Created by liuml on 2022/4/14 10:47*/
public class DataObject {
}

1. 写module类 (注解Module). Provides方法提供对象(Provides注解).


@Module
public class HttpModule {@Providespublic HttpObject providerHttpObject(){return new HttpObject();}
}

2. Component 创建

/*** Created by liuml on 2022/4/14 10:50* 组件 用来放module的 需要那些module*/
@Component(modules = {HttpModule.class, DataModule.class})
public interface MyComponent {//这里的参数不能用多态void inject(MainActivity activity);}

3. 在activity里面注入并调用

public class MainActivity extends AppCompatActivity {String TAG = "MainActivity";//注入后直接用@InjectHttpObject httpObject;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);DaggerMyComponent.create().inject(this);httpObject.post();Log.d(TAG, "onCreate: httpObject "+httpObject.hashCode());}
}

//也可以使用建造者模式 方便动态修改参数,传递参数DaggerMyComponent.builder().build().inject(this);

打印结果


2022-04-15 10:36:29.807 14293-14293/com.demo.ioc_project D/HttpObject: HttpObject post: post请求数据
2022-04-15 10:36:29.807 14293-14293/com.demo.ioc_project D/MainActivity: onCreate: httpObject 38794633

4. 单例使用


局部单例

如果在model中使用了单例, 那么在Component中也需要使用单例注解


model类


/*** Created by liuml on 2022/4/14 10:48** 这个类用来提供对象*/
@Module
public class HttpModule {@Singleton@Providespublic HttpObject providerHttpObject(){return new HttpObject();}
}

Component组件


/*** Created by liuml on 2022/4/14 10:50* 组件 用来放module的 需要那些module*/
@Singleton
@Component(modules = {HttpModule.class, DataModule.class})
public interface MyComponent {//这里的参数不能用多态void inject(MainActivity activity);}

注入使用

public class MainActivity extends AppCompatActivity {String TAG = "MainActivity";//注入后直接用@InjectHttpObject httpObject;@InjectHttpObject httpObject2;private TextView tvTest;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tvTest = findViewById(R.id.tv_test);DaggerMyComponent.create().inject(this);DaggerMyComponent.builder().build().inject(this);tvTest.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {DaggerMyComponent.builder().build().inject(MainActivity.this);}});httpObject.post();Log.d(TAG, "onCreate: httpObject " + httpObject.hashCode());Log.d(TAG, "onCreate: httpObject2 " + httpObject2.hashCode());//也可以使用建造者模式 方便动态修改参数,传递参数}
}

打印结果

2022-04-15 16:49:49.755 11157-11157/com.demo.ioc_project D/MainActivity: onCreate: httpObject 197891620
2022-04-15 16:49:49.755 11157-11157/com.demo.ioc_project D/MainActivity: onCreate: httpObject2 197891620

两个对象都是一个


全局单例

如果新建一个activity. 在新的activity里面进行注入对象. 如果这个对象用了新的Component注入对象,那么


5. 多个Component组合依赖

在实际项目中,可能存在多个Component,那么需要把代码注入到某个类中,但是dagger2不允许两个或者两个以上的Component注入到同一个类. 这个时候就需要使用组合依赖.

预览

预览


  1. 依赖方式

一个Component可以依赖一个或者多个Component,采用的是@Component的dependencies属性

如下


/*** Created by liuml on 2022/4/14 10:50* 组件 用来放module的 需要那些module*/
@Singleton
@Component(modules = {HttpModule.class, DataModule.class}, dependencies = {PresenterComponent.class}
)
public interface MyComponent {//这里的参数不能用多态void inject(MainActivity activity);void injectSecActivity(SecActivity activity);}

  1. 包含方式

这里就用到了@SubComponent注解,用这个注解标记接口或者抽象类,表示它可以被包含。一个Component可以包含一个或者多个Component,而且被包含的Component还可以继续包含其他的Component。


  1. 继承方式

注意几点:


  1. Component的作用域 必须跟 对应的Module作用域一致。如果@Module没有标记作用域,那就不影响。

  2. Component 和 依赖的Component作用域范围不能一样,否则会报错。一般来讲,我们应该对每个Component都定义不同的作用域。

  3. @Singleton并不是真的能创建单例,但是我们依然可以保证在App的生命周期内一个类只存在一个对象。@Singleton更重要的作用是通过标记来提醒我们自己来达到更好的管理实例的目的。


作用域@Scope

Dagger2中有一个现成的作用域注解,那就是@Singleton

@Scope 它声明依赖的作用域。换句话说,范围注解是为了定义实例的生命周期,在此生命周期内,实例属于单例模式,一旦离开生命周期,实例将被回收,内存空间得到释放。

简单理解就是:@Scope 注解标记在自定义注解上,指导注入器如何重用实例。

前面讨论的 @Singleton 就是用 @Scope 标记的注解,可以用来生成全局单例依赖。

@Scope 通过标记自定义注解,帮助我们 划分单例所属生命周期。

在 Application 中,使用 @Singleton 内置注解标记全局单例
在 Activity 中,使用 @ActivityScoped 自定义注解标记页面单例
可以认为,@Scope 实际上就是单例模式,只是用不同的命名表示不同的单例生效范围。


使用Scope 注意两点

scope&dependencies的使用


  1. 多个component上面的scope不能相同
  2. 没有scope的组件不能去依赖有scope的组件

6. 组合的其他用法

两个 Component 之间除了 dependencies 依赖方式以外,还可以使用 Subcomponent 方式。

和 dependencies 的区别:

被依赖的 Component 不需要显示声明 Module 中对应的 provideXXX() 方法
初始化的时候不需要使用 DaggerXXXComponent 创建被依赖的 Component 对象
dependencies:被依赖的 Component 有 Scope 修饰时,依赖方必须使用 Scope 且不可与前者的 Scope 相同;
Subcomponent:被依赖的 Component 有 Scope 修饰时,依赖方可以不使用 Scope,也可以使用 Scope 但不能与前者的 Scope 相同;
相同点是:被依赖的 Component 没有 Scope 修饰时,依赖方是否使用 Scope 没有要求。

那么使用SubComponent和Component中添加dependencies的区别是啥呢?

Component Dependencies - Use this when:

// 你想保持两个组件之间的独立you want to keep two components independent.// 你想强调一个组件是依赖于另一个组件you want to explicitly show what dependencies from one component is used by the other.

Subcomponents - Use this when:

// 你想让一个组件保持高内聚(不想直接暴露子组件的实例化过程)
you want to keep two component cohesive.
// 你并不在意明确展示出两个组件之间的依赖关系(哪个组件依赖哪个组件)
you may not care to explicitly show what dependencies from one component is used by the other.

3. dagger注入原理源码分析


实际上是通过apt技术生成了代码

如下图

生成代码


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
author-avatar
哇哈哈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有