文章目录

  • 一、前言
  • 二、添加依赖
  • 三、简单示例
  • 四、作用域
  • 五、自定义作用域
  • 六、@Binds 和 @Provides
  • 七、关于Dagger为什么在Android中要比Hilt复杂
  • 八、inject(Activity act)的用法
  • 十、参考链接

一、前言

Hilt是对Dagger的封装处理,这里对其进行下简单介绍。

二、添加依赖

    implementation 'com.google.dagger:dagger:2.41'kapt 'com.google.dagger:dagger-compiler:2.41'

三、简单示例

class UserRepository @Inject constructor(private val localDataSource: UserLocalDataSource,private val remoteDataSource: UserRemoteDataSource
) {fun printUserName(){localDataSource.printUserName()}
}// @Inject lets Dagger know how to create instances of these objects
class UserLocalDataSource @Inject constructor() {fun printUserName(){Log.e("YM--->","---获取用户姓名")}
}
class UserRemoteDataSource @Inject constructor() {  }
@Component
interface ApplicationGraph {// The return type  of functions inside the component interface is// what can be provided from the containerfun repository(): UserRepository
}
class DaggerActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_dagger)// Create an instance of the application graphval applicationGraph: ApplicationGraph = DaggerApplicationGraph.create()// Grab an instance of UserRepository from the application graphval userRepository: UserRepository = applicationGraph.repository()userRepository.printUserName()}
}

需要注意的是,写完后需要重新build下才能生成DaggerApplicationGraph类。另外需要注意的是Dagger 在每次收到请求时都会创建 UserRepository 的新实例。所以以下两种实例对象不是一个对象


val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create()val userRepository: UserRepository = applicationGraph.repository()
val userRepository2: UserRepository = applicationGraph.repository()assert(userRepository != userRepository2)

如果要是需要多个依赖项目共用一个实例的话,需要引入作用域的概念

四、作用域

修改代码为如下

@Singleton
class UserRepository @Inject constructor(private val localDataSource: UserLocalDataSource,private val remoteDataSource: UserRemoteDataSource
) {fun printUserName(){localDataSource.printUserName()}
}
@Singleton
@Component
interface ApplicationGraph {// The return type  of functions inside the component interface is// what can be provided from the containerfun repository(): UserRepository
}

五、自定义作用域

暂时不知道自定义作用域的目的,这里仅仅做个记录
将代码修改为以下可以实现同一目的

@Scope
@MustBeDocumented
@Retention(value = AnnotationRetention.RUNTIME)
annotation class MyCustomScope
@MyCustomScope
@Component
interface ApplicationGraph {// The return type  of functions inside the component interface is// what can be provided from the containerfun repository(): UserRepository
}
@MyCustomScope
//@Singleton
class UserRepository @Inject constructor(private val localDataSource: UserLocalDataSource,private val remoteDataSource: UserRemoteDataSource
) {fun printUserName(){localDataSource.printUserName()}
}

六、@Binds 和 @Provides

dagger的使用和Hilt的用法一直,这里不再记录,详情参考Hilt一章

七、关于Dagger为什么在Android中要比Hilt复杂

为什么Dagger在Android中会比Hilt用起来复杂?这是因为通常来说,Dagger生成对象需要通过构造函数来生成,但是由于某些 Android 框架类(如 Activity 和 Fragment)由系统实例化,因此 Dagger 无法为您创建这些类。因此生成起来就比较麻烦的多。所以对于这些类必须使用字段注入。举个例子,假设我们想在一个类里面使用Activit对象,我们是没有办法通过构造函数的方式生成这个对象的,比如如下代码


@Inject lateinit var act: Activity

虽然定义了Activity,但是却没有办法去生成它。
详情参考dagger官网

八、inject(Activity act)的用法

通常的方式是通过一个 inject()函数进行绑定,代码如下

class UserViewModel @Inject constructor(){fun test(){Log.e("YM","======")}
}
@Component
interface UserComponent{fun inject(activity: DaggerActivity)
}
class DaggerActivity : AppCompatActivity() {@Inject lateinit var useViewModel: UserViewModeloverride fun onCreate(savedInstanceState: Bundle?) {DaggerUserComponent.create().inject(this)super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)useViewModel.test()}
}

如果不使用fun inject(activity: DaggerActivity)进行绑定,那么使用useViewModel时候就会出现未初始化的问题。这里可以查看下一个生成的代码

@DaggerGenerated
@SuppressWarnings({"unchecked","rawtypes"
})
public final class DaggerUserComponent implements UserComponent {private final DaggerUserComponent userComponent = this;private DaggerUserComponent() {}public static Builder builder() {return new Builder();}public static UserComponent create() {return new Builder().build();}@Overridepublic void inject(DaggerActivity activity) {injectDaggerActivity(activity);}private DaggerActivity injectDaggerActivity(DaggerActivity instance) {DaggerActivity_MembersInjector.injectUseViewModel(instance, new UserViewModel());return instance;}public static final class Builder {private Builder() {}public UserComponent build() {return new DaggerUserComponent();}}
}
@QualifierMetadata
@DaggerGenerated
@SuppressWarnings({"unchecked","rawtypes"
})
public final class DaggerActivity_MembersInjector implements MembersInjector<DaggerActivity> {private final Provider<UserViewModel> useViewModelProvider;public DaggerActivity_MembersInjector(Provider<UserViewModel> useViewModelProvider) {this.useViewModelProvider = useViewModelProvider;}public static MembersInjector<DaggerActivity> create(Provider<UserViewModel> useViewModelProvider) {return new DaggerActivity_MembersInjector(useViewModelProvider);}@Overridepublic void injectMembers(DaggerActivity instance) {injectUseViewModel(instance, useViewModelProvider.get());}@InjectedFieldSignature("com.dagger.application.dagger.DaggerActivity.useViewModel")public static void injectUseViewModel(DaggerActivity instance, UserViewModel useViewModel) {instance.useViewModel = useViewModel;}
}

通过生成的代码可以看出是关联过程的。

九、作用域和子组件
这一章节不算复杂,这里将代码贴出作为记录

// @Inject lets Dagger know how to create instances of this object
@Singleton
class UserRepository @Inject constructor(private val localDataSource: UserLocalDataSource,private val remoteDataSource: UserRemoteDataSource
) {fun printUserName(){//        localDataSource.printUserName()remoteDataSource.printUserName()}
}// @Inject lets Dagger know how to create instances of these objects
class UserLocalDataSource @Inject constructor() {fun printUserName(){Log.e("YM--->","---获取用户姓名")}
}
class UserRemoteDataSource @Inject constructor( private val loginService: LoginRetrofitService) {fun printUserName(){Log.e("YM--->","---remote")}
}class LoginRetrofitService @Inject constructor(){}
@Module
class NetworkModule {// @Provides tell Dagger how to create instances of the type that this function// returns (i.e. LoginRetrofitService).// Function parameters are the dependencies of this type.@Providesfun provideLoginRetrofitService(): LoginRetrofitService {// Whenever Dagger needs to provide an instance of type LoginRetrofitService,// this code (the one inside the @Provides method) is run.return LoginRetrofitService()}
}// The "subcomponents" attribute in the @Module annotation tells Dagger what
// Subcomponents are children of the Component this module is included in.
@Module(subcomponents = [LoginComponent::class])
class SubcomponentsModule {}
@ActivityScope
class LoginViewModel @Inject constructor(private val userRepository: UserRepository) {fun toast(){Log.e("YM","======")}
}
@Singleton
@Component(modules = [NetworkModule::class, SubcomponentsModule::class])
interface ApplicationGraph {// The return type  of functions inside the component interface is// what can be provided from the containerfun repository(): UserRepository
//    fun inject(activity: Application)// This function exposes the LoginComponent Factory out of the graph so consumers
// can use it to obtain new instances of LoginComponentfun loginComponent(): LoginComponent.Factory
}// Definition of a custom scope called ActivityScope
@Scope
@Retention(value = AnnotationRetention.RUNTIME)
annotation class ActivityScope// Classes annotated with @ActivityScope are scoped to the graph and the same
// instance of that type is provided every time the type is requested.
@ActivityScope
@Subcomponent
interface LoginComponent {@Subcomponent.Factoryinterface Factory {fun create(): LoginComponent}fun inject(activity: DaggerActivity)//    fun activity(): DaggerActivity}
@Singleton
@Component(modules = [NetworkModule::class, SubcomponentsModule::class])
interface ApplicationGraph {// The return type  of functions inside the component interface is// what can be provided from the containerfun repository(): UserRepository
//    fun inject(activity: Application)// This function exposes the LoginComponent Factory out of the graph so consumers
// can use it to obtain new instances of LoginComponentfun loginComponent(): LoginComponent.Factory
}// Definition of a custom scope called ActivityScope
@Scope
@Retention(value = AnnotationRetention.RUNTIME)
annotation class ActivityScope// Classes annotated with @ActivityScope are scoped to the graph and the same
// instance of that type is provided every time the type is requested.
@ActivityScope
@Subcomponent
interface LoginComponent {@Subcomponent.Factoryinterface Factory {fun create(): LoginComponent}fun inject(activity: DaggerActivity)//    fun activity(): DaggerActivity}
class DaggerApp: Application() {val appComponent = DaggerApplicationGraph.create()
}
class DaggerActivity : AppCompatActivity() {@Injectlateinit var loginViewModel: LoginViewModellateinit var loginComponent: LoginComponentoverride fun onCreate(savedInstanceState: Bundle?) {val applicationGraph: ApplicationGraph = (applicationContext as DaggerApp).appComponentapplicationGraph.repository().printUserName()loginComponent = applicationGraph.loginComponent().create()// Make Dagger instantiate @Inject fields in LoginActivityloginComponent.inject(this)super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)loginViewModel.toast()}
}

十、参考链接

  1. Dagger 基础知识

Dagger的使用一相关推荐

  1. dagger android,dagger.android多模块项目实现

    本文适合有一定的Dagger2使用基础的同学 前两篇文章我们讲了两种多模块项目怎么使用Dagger2. 发现在每个Activity的onCreate中都需要调一个inject方法NewsCompone ...

  2. Android 依赖注入: Dagger 2 实例解说(一)

    本文原创,转载请注明出处:http://blog.csdn.net/zjbpku [Duplicated]   link to  Dagger on Android - Dagger2具体解释 关于D ...

  3. 用 Dagger 2 实现依赖注入

    原文地址:Dependency Injection with Dagger 2 原文作者:CodePath 译文出自:掘金翻译计划 译者: tanglie1993 校对者:mnikn, Zhiw 用 ...

  4. 开发日记-20190508 关键词 dagger Idea插件

    插件编写参考: https://www.jianshu.com/p/b0c7218678d8 IntelliJ IDEA编写插件入门(1):自动创建代码 https://github.com/Fran ...

  5. Dagger依赖注入注解的具体作用

    说真的,其实一开始说dagger并不依赖反射,其实我还是有点感兴趣的,因为通过注解来直接获取对应的对象本身其实也是很方便的一种东西,不过貌似对于性能还是有一定的影响的,不过,就个人而言,这种细枝末节的 ...

  6. 单元测试以及dagger的使用

    最近对测试比较敏感,因为涉及了代码重构,虽然我是很有自信的一个人,但是过度严谨的强迫症很多时候让我很尴尬. 所以还是希望面对源代码有一定的测试代码,以方便验证代码重构之后的正确与否. 所以,游戏开始了 ...

  7. Android 依赖注入可以更简单 —— 新版本 Dagger 2 使用教学

    今年 3 月 21 号 Dagger 2 在 2.10 版本之后针对 Android 方面做了很大的优化,使用方法也随之有了不少变化.本次改动除了让 Dagger 2 的使用更加符合控制反转原则,还针 ...

  8. Dagger简单Demo

    Dagger实现依赖注入,为了解决程序直接的耦合度. 本例子主要为了实现简单的依赖注入 配置: Project级别的build.gradle // Top-level build file where ...

  9. Android开源框架——依赖注入Dagger

    介绍:Dagger是Square公司开发依赖注入框架,主要针对辅助类对象,而ButterKnife是针对View视图对象的. github:https://github.com/square/dagg ...

  10. [Android]使用Dagger 2进行依赖注入 - Producers(翻译)

    使用Dagger 2进行依赖注入 - Producers 原文:http://frogermcs.github.io/dependency-injection-with-dagger-2-produc ...

最新文章

  1. 批量计算多个点到一个点的距离
  2. 软件架构设计(第2版)——程序员向架构师转型必备
  3. 2.9 情感分类-深度学习第五课《序列模型》-Stanford吴恩达教授
  4. 各自然带代表植被_植被垂直带谱?水与热之间的较量。
  5. 上次那个上门要源代码的女网红,后来咋样了?
  6. 无透镜成像相关资料汇总
  7. php多个地方ping,同时ping多个ip找了最快的ip网的php实例-PHP源码
  8. SAP License:SAP CO ML 物料帐配置
  9. GDB+coredump定位段错误
  10. 彩虹查课插件 使用说明 网课查询插件 极速版
  11. 物联网5种无线传输协议特点大汇总
  12. 使用jemeter进行接口压力测试
  13. 腾讯、淘宝的架构大数据你有了解么?大数据技术及算法为你解析
  14. RecyclerView侧滑删除
  15. HTML星星组成的平行四边形,用一个程序打印菱形,平行四边形星星图
  16. 数据链路层的主要功能与服务
  17. 计算机病毒1000字,《大鱼海棠》观后感1000字
  18. Java读写Excel原来这么简单
  19. ax88772c linux驱动下载,ax88772c以太网驱动问题
  20. Ps Camera Raw 打开图像错位花屏原因- PC 上的独立显卡背锅

热门文章

  1. 无锡鼋头渚-樱花谷的美丽传说
  2. 当代第一IT诗人代腾飞在线互动访谈精彩问答(下)(转)
  3. 持续集成工具hudson
  4. idea中 当你的代码已经提交并且成功push到服务器上去了 但是文件名还是显示蓝色 再次提交还是会自动选中哪些蓝色文件 idea的terminal没有办法输入命令
  5. 狂神JUC——8锁现象彻底理解锁
  6. SSM+mysql+微信小程序超市外卖系统-计算机毕业设计源码97313
  7. 写给想成为游戏原画师的新人们
  8. 网付:超八成商家开通线上渠道,小程序成零售数字化经营利器
  9. 【极简壁纸】桌面壁纸美图推荐_2019/01/27
  10. 理解ROC曲线,TPR与FPR