Hilt原理分析一(Hilt技术概览)

简介: Hilt原理分析一(Hilt技术概览)

系列文章

在分析Hilt的原理之前,先搞清楚Hilt的一些黑魔法,这样在后面的原理分析的时候,才不会疑惑一些类是怎么冒出来的,以及为什么要多出这些类。

既然是原理分析,肯定离不开代码,因为这一节主要是要搞清楚Hilt整体的设计原理,所以我们先从最简单,也是使用Hilt必不可少的一步开始,对自定义的Application使用@HiltAndroidApp注解,源码如下

@HiltAndroidApp
class MyApplication : Application() {
}

只从这段代码,也看不出什么,那么为什么在使用Hilt的时候必须要加入这段代码呢?既然源码看不出什么,那么就看下经过编译后会有什么变化。

编译后的变化

代码编译后的一些产物会出现在模块的build/intermediates目录下,进入这个目录会发现有一个hilt的文件夹,看下里面的文件,如下

b0f0167ff026204ebd05b582c058d32.png

可以发现这里的四个类都与MyApplicaiton有关,将这四个类大致的看了一下,会发现Hilt_MyApplication类与MyApplication关系最大,可以看下代码

d8ee46a494041daa33225e9bb76b522.png

发现Hilt_MyApplication继承Application,到这里就有疑问了,我们自己写的MyApplication是继承Application的,这里又有一个继承Application的,而Android的一个进程只有一个Application类,那么这个编译后生成的类,和我们自己的Application有什么关系呢?想要知道答案,我们就看下最后生成的dex文件里,它们两个的关系。

Hilt_MyApplication与MyApplication

用Android Studio自带分析apk的工具打开编译后的apk,结构如图

042b2ab1a3e8de4ff82bea1d89143ae.png

依次查找这几个dex文件,最后在classes4.dex文件中找到了MyApplication,查看编译后的字节码如下

819d6d3566bfc8c1f78b728045cc38e.png

可以看到MyApplication继承了HIlt_MyApplication,到这里算是搞明白了它们两个的关系。关于Hilt_MyApplication具体的作用,下篇文章会详细介绍。那么问题来了,Hilt是怎么做到生成Hilt_MyApplication类以及怎么让MyApplication继承Hilt_MyApplication的呢?

Hilt的黑魔法

不知道HIlt原理的话,会觉得下面的两个问题是黑魔法

  • Hilt是怎么做到生成Hilt_MyApplication类?
  • 怎么让MyApplication继承Hilt_MyApplication的呢?

如果知道原理的话,就会觉的“哦,原来是这么回事”。

Hilt是怎么做到生成Hilt_MyApplication类?

先来看第一个问题,还记得吗?在MyApplication类上面有@HiltAndroidApp注解,其实生成HIlt_MyApplication类,就用到了这个注解。用到的技术就是Annotation Processing Tool(简称APT),

APT 是一种处理注释的工具, 它对源代码文件进行检测找出其中的注解,并使用注解进行额外的处理。

通俗的解释一下就是: 在源码编译时查找特特定注解标记的类、字段或者方法,对这个注解标记的类、字段或者方法做一些额外的处理,可以生成新的代码,增加业务逻辑等。 这里生成Hilt_MyApplication类就是用到的APT技术,不了解这个技术的话,可以查找一些资料,这个不是本文的重点。

再看下第二个问题,这个就说来话长了,因为涉及的内容较多,这里就长话短说,说下用到的技术,不理解的话,也是需要自己查阅相关资料。看下由Java或Kotlin生成dex文件的过程,如图

08c7a9aef9c0dd8e6e7cd4ae0cc8d2e.png

过程就是源码->class文件->dex文件,像上面第一个问题提到的APT技术的处理时机,就是在源码->class文件这一步,就是上图第一个红色虚线那里做的处理。

怎么让MyApplication继承Hilt_MyApplication的呢?

第二个问题就是在class文件->dex文件这一步做的处理,这里用到的技术就是修改字节码,常用的修改字节码的库是“ASM”,当然Hilt对字节码的处理也是用的这个库,可以在看下经过增加了ASM处理步骤后的图,比较下与上图有什么不同

d1ae0f446c3123e6919ee8dfb1155aa.png

就是在class文件->dex文件这一步用ASM对字节码文件做修改,就是这一步修改了字节码,让MyApplication继承至Hilt_MyApplication的。到这里又会有问题产生,那么Hilt是怎么干涉编译过程,利用ASM修改字节码的呢?

这个问题就涉及到Gradle的Plugin了,不了解Gradle的Plugin可以看下我的这篇文章,还记得导入Hilt的一些步骤吗?如下

98297e76e2679c9ccc72c63d4b25bc2.png

红框内的就是引入Hilt的Gradle的Plugin,通过Hilt的Plugin就可以在编译的过程插入自己的一些处理逻辑。

简单的看下Hilt的Plugin插件的源码,文件在/Users/xxx/.gradle/caches/modules-2/files-2.1/com.google.dagger/hilt-android-gradle-plugin目录下,

7be81157b979cd750f961bf0e5021cd.png

这里是根据Gradle插件的版本不同,做不同的处理,接着看下继承HIlt_XXX 的核心源码,如下

9a4fd1e038b0bc430f8feb8793bd46c.png

其实,问题2 涉及的做技术还是比较多的,这里我总结下用到的主要技术,不了解的话可以自己查阅相关资料

  • ASM
  • Gradle的Plugin
  • Gradle的Transform

看到这里是不是对Hilt的黑魔法有了基本的了解了呢?相信有了这些基本的认知,后面对源码的分析的文章,你一定会理解的更好。

总结

本文主要是回答了可能对Hilt的一些疑问,如生成的这些类与我们自己的类的关系,这些类是怎么产生出来的以及Hilt是怎么做到让我们自己的类来继承Hilt生成的类的。 文章主要是介绍Hilt利用了什么技术做到这些的,关于里面用到的一些技术,并不是本文的重点,如果不了解相关技术,可以自己查阅资料,相信了解了相关知识后,你会对Hilt有更深的理解。


相关文章
|
2月前
|
存储 安全 Android开发
从 Component Tree 视角看 Dagger 到 Hilt 的演变
从 Component Tree 视角看 Dagger 到 Hilt 的演变
79 0
|
移动开发 ARouter 开发工具
开源最佳实践:Android平台页面路由框架ARouter
为了更好地让开发者们更加深入了解阿里开源,阿里云云栖社区在3月1号了举办“阿里开源项目最佳实践”在线技术峰会,直播讲述了当前阿里新兴和经典开源项目实战经验以及背后的开发思路,在本次在线技术峰会上,阿里云资深开发工程师刘志龙分享了Android平台页面路由框架ARouter的技术方案、解决的问题以及在实际场景中的最佳实践。
47104 2
|
ARouter 索引
|
10天前
|
Java Android开发
程序与技术分享:Android使用Dagger注入的方式初始化对象的简单使用
程序与技术分享:Android使用Dagger注入的方式初始化对象的简单使用
|
Android开发
Dagger Hilt - ViewModel的依赖注入及实现原理
Dagger Hilt VIewModel 依赖注入的原理
417 0
|
存储 运维 Dubbo
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
> Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双 11 基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实践和统一标准,同时将规模化实践经验与技术创新贡献开源社区,极大的推动了开源技术与标准的发展。 > 本文
436 0
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
|
前端开发 Android开发 开发者
Dagger Hilt - Android官方推荐的依赖注入框架
Dagger Hilt 帮助 Android 项目实现依赖注入
537 0
DHL
|
算法 Java Shell
全方面分析 Hilt 和 Koin 性能
这是 Hilt 系列的第四篇,主要来分析 Hilt 和 Koin 的性能,如果你之前对 Hilt 和 Koin 不了解也没有关系,对阅读本文没有什么影响
DHL
524 0
全方面分析 Hilt 和 Koin 性能
|
Java Android开发
【Android 插件化】Hook 插件化框架 ( 从源码角度分析加载资源流程 | Hook 点选择 | 资源冲突解决方案 )(一)
Android 插件化】Hook 插件化框架 ( 从源码角度分析加载资源流程 | Hook 点选择 | 资源冲突解决方案 )(一)
239 0