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

dagger2入门指南

dagger2入门指南配置Dagger2参考Dagger2Wiki,在Gradle中添加以下依赖dependencies{providedjavax.annotation:java

dagger2入门指南

配置Dagger2

参考Dagger2 Wiki,在Gradle中添加以下依赖


dependencies {
provided 'javax.annotation:javax.annotation-api:1.2'
compile 'com.google.dagger:dagger:2.0.2'
apt 'com.google.dagger:dagger-compiler:2.0.2'
}

apt是一个Gradle插件,协助Android Studio 处理Annotation Processors,所以在Gradle中还必须添加以下内容(关于Android-apt更多内容参考)


dependencies {

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}

apply plugin: 'com.neenbedankt.android-apt'
开始使用

Dagger2是实现依赖注入的一种手段,关于依赖注入,这里就不多介绍,想了解的可以参考, Dagger2中需要使用注解来完成依赖注入,我们来一个个介绍这些注解

@Inject

我们可以使用@Inject这个注解来标注目标类中所依赖的其他类,也可以用来标注所依赖的其他类的构造函数。举个例子


public class Human{

@Inject
Father father;
}

public class Father{

@Inject

public Father(){ //如果标注有参数的构造方法,在调用构造方法前会去获取参数对应的对象

}
}

Human需要通过@Inject注入Father这个类的时候,会先调用Father中标注的构造函数,生成相应的对象。这样HumanFather之间就有了一种无形的联系,但是仅仅这样还不够,我们还需要用到Component来使他们连接起来

@Component

@Component的作用就是连接目标类和目标类依赖实例(可以通过上面说的@Inject标注构造函数也可以通过@Module来产生)。那Component是怎么工作的呢?

  • 查找目标类中用@Inject标注的属性

  • 查找对应属性依赖实例

  • 将依赖实例进行赋值

目标类需要初始化自己依赖的其他类还需要调用Component的inject(Object object)方法开始注入

@Singleton @Component(modules = { ApplicationModule.class},dependencies={xxxComponent.class})
public interface ApplicationComponent {
Context getContext();
void inject(MyApplication mApplication);
}

比如在MyApplication中需要注入其他类,则需要在MyApplication中调用ApplicationComponentinject方法开始注入。

  • modules对应的就是提供依赖的Module类,可以有多个
  • dependencies表示该Component还依赖其他Component
  • @Singleton是一种Scope注解,下面会说到

@Module

介绍@Inject的时候我们说过,可以通过@Inject标注构造函数生成对应的对象,但是如果是第三方类库,我们无法添加@Inject注解的时候该怎么办,这时候就需要用到@Module了。举个列子


@Modulepublic class Module{

//A是第三方类库中的一个类

@Provides
A provideA(){

return A();

}}

  • 通过provideA()这个方法我们就可以生成一个A的实例,目标类中可以通过@Inject来注入

  • @provides标注的方法直接返回以创建或者新创建的对象,只在Module中使用

  • Component会首先从Module中查找需要注入的实例,如果找到了,则停止,如果没有找到则是继续从Inject标注的构造函数查找

@Qualifier

通过上面我们知道,创建类的实例有两种方式,这两个方式有先后之分,但是如果一个类在同一方式下有多个创建类的方法的时候,Component会选取哪个方法来创建这个类的实例呢?举个例子

@Module
public class Module{

@Provides
A provideA(){
return A();
}

@provides
A provideOtherA(){
return A();
}
}

如果我们按照上面这样写,Dagger2在编译的时候就会报错,那么我们改如何解决呢?这时候就需要用到@Qualifier了,我们可以用这个注解给不同的创建实例的方法进行标识并加以区分。

@Module
public class Module{

@Named("firstA")
@Provides
A provideFirstA(){
return A();
}
@Named("secondA")
@provides
A provideSecondA(){
return A();
}
}

@Named是Dagger2对于@Qualifier一个默认实现,我们也可以自定义,比如@ForApplication@ForAcitivity来标识不同的Context

@Qualifier
@Documented
@Retention(RUNTIME)
public @interface Named {
/** The name. */
String value() default "";
}

这样,通过@Named我们就可以区分不同的实例了

public class Human{
@Inject
@Named("firstA")
A firstA;
@Named("secondA")
@provides
A secondA;
}

@Scope

Scope是一个注解作用域,通过自定义注解限定对象的作用范围。通过这个注解能够解决不同对象生命周期不一致的问题,比如Application,ToastHelper等存在于应用的整个生命周期,Adapter,Presenter等则随着Activity的销毁而销毁。我们可以通过自定义不同的Scope来区分。举个例子

@Scope
@Documented
@Retention(RUNTIME)
public @interface PerApp{}

@PerApp @Component(modules = { ApplicationModule.class})
public interface ApplicationComponent {
Context getContext();
void inject(MyApplication mApplication);
}

@Module
public class ApplicationModule {
private final Context context;
public ApplicationModule(Context context) {
this.cOntext= context;
}
@Provides @PerApp public Context provideApplicationContext() {
return context.getApplicationContext();
}
}

我们在ApplicationModule中定义了创建Context实例的方法,在ApplicationComponent中管理ApplicationModule,因为ApplicationComponent只有在Application中实例化一次,所以Context的生命周期也就和Application一样了,也就是Dagger并不会帮你管理生命周期,只能自己来控制。那么PerApp这个注解有什么用呢?

  • 更好的管理ComponentModule之间的匹配关系,Dagger2在编译的时候会检查Component管理的Module,若发现Component所标注的自定义Scope注解与Module中不一样,就会报错。
  • 提高可读性,通过PerApp就知道是在整个Application有小范围内

注意点:

  • 一个Module中只能存在一种Scope
  • Scope标注的Component和所依赖的ComponentScope不能一样
实例讲解

创建ApplicationComponent

@PerApp
@Component(modules = { ApplicationModule.class })
public interface ApplicationComponent {
Context getContext();
ToastUtils getToastUtils();
}

ApplicationComponent是一个全局的Component,负责管理整个App的全局类实例,Context getContext();ToastUtils getToastUtils();是将ContextToastUtils暴露给子Component。

创建ApplicationModule

@Module
public class ApplicationModule {
private final MyApplication myApplication;
public ApplicationModule(MyApplication myApplication) {
this.myApplication = myApplication;
}
@PerApp @Provides Context provideContext() {
return myApplication.getApplicationContext();
}
@PerApp @Provides ToastUtils provideToastUtils(Context mContext) {
return new ToastUtils(mContext);
}
}

ApplicationModule生成全局ContextToastUtils实例

在Application中创建ApplicationComponent实例

public class MyApplication extends Application {
private ApplicationComponent mApplicationComponent;
@Override public void onCreate() {
super.onCreate();
mApplicatiOnComponent=
DaggerApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build();
}
public ApplicationComponent getApplicationComponent() {
return mApplicationComponent;
}
}

DaggerApplicationComponent这个是有Dagger2生成的类,因为ApplicationComponent只初始化一次,所以注入的类都是单例的,这就是Dagger2真正创建单例的方法。

划分Component

一个应用应该包含一个全局的Component,负责管理整个全局类的实例,其他Componet建议按照页面来划分。

@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = {
MainModule.class, ActivityModule.class
})
public interface MainComponent {
void inject(MainActivity mActivity);
}

@Module
public class MainModule {
@PerActivity @Provides GetUser getUser() {
return new GetUser();
}
}

@PerActivity
@Component(modules = { ActivityModule.class })
public interface ActivityComponent {
Activity getActivity();
}

@Module
public class ActivityModule {
private final Activity mActivity;
public ActivityModule(Activity mActivity) {
this.mActivity = mActivity;
}
@Provides @PerActivity Activity provideActivity() {
return mActivity;
}
}

上面是Main这个页面的划分

DEMO

demo


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • ScrollView嵌套Collectionview无痕衔接四向滚动,支持自定义TitleView
    本文介绍了如何实现ScrollView嵌套Collectionview无痕衔接四向滚动,并支持自定义TitleView。通过使用MainScrollView作为最底层,headView作为上部分,TitleView作为中间部分,Collectionview作为下面部分,实现了滚动效果。同时还介绍了使用runtime拦截_notifyDidScroll方法来实现滚动代理的方法。具体实现代码可以在github地址中找到。 ... [详细]
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社区 版权所有