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

哔哩哔哩在Hilt组件化的使用技术探索

这篇文章主要为大家介绍了哔哩哔哩在Hilt组件化的使用技术探索,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

DI(Dependency Injection),即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

最近业务同学需要接入谷歌推的Hilt框架。因为哔哩哔哩的业务上很容易出现业务层面的交叉,而因为项目完成了大量的组件化拆分。由于不希望业务之间产生相互引用,所有在技术评估完成之后我们决定由我们部门来对Hilt进行接入。

接入Hilt

摘自官方文档 使用 Hilt 实现依赖项注入

首先先声明下dagger.hilt.android.plugin相关的plugin。

buildscript {
    ...
    dependencies {
        ...
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.35.1'
    }
}

其次由于hilt一大部分相关的都是基于kapt的代码生成逻辑,所以我们要在使用到hilt的模块的build.gradle中都定义如下相关的。

...
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'

android {
    ...
}

dependencies {
    implementation "com.google.dagger:hilt-android:2.35.1"
    kapt "com.google.dagger:hilt-android-compiler:2.35.1"
}

我们需要给我们的Application增加一个注解。

@HiltAndroidApp
class ExampleApplication : Application() {  }

根据官方接入文档哦,我们组只要把Application只要打上@HiltAndroidApp的注解,就可以完成这部分接入能力了。

Hilt在组件化

但是但是官方有个声明是这样的。

Hilt 代码生成操作需要访问使用 Hilt 的所有 Gradle 模块。编译 Application 类的 Gradle 模块需要在其传递依赖项中包含所有 Hilt 模块和通过构造函数注入的类。

从这部分说明上来看,这个注解最好是能放在com.android.application模块中, 这样就能保证依赖到所有的子模块中去了。

但是实际我们在使用过程中,由于com.android.application模块还是有一些代码量的,而由于kapt代码生成机制,需要先将kotlin代码转化成java代码,之后才能生成ast语法树。

根据ci上的实验结果,在com.android.application模块下kapt耗时在30s左右,而整体编译时间大概为3分钟左右。这种耗时我个人觉得还是属于不能接受的。

所以我们调整了下这部分代码。这次建立了一个壳module,这边只有HiltApplication的注解相关。然后将这个module依赖了所有业务仓库,按照编译逻辑来说,基于gradle task的depend逻辑,他会在application模块编译之前,所有业务模块编译之后,这样能保证hilt生成的代码逻辑正常。

同时由于是一个空工程,我们把空工程定义为bundle-kapt,所以整体来说对于编译速度影响会变到最小。让各位大佬看下我们后续的优化结果。

上述是我最后截图出来的结果,我们将一个耗时大概30s的任务优化到3s,其实效果上来说已经非常明显,达到我们想要的预期了已经。

当然如果后续hilt支持了ksp之后,这部分速度应该可以更快,毕竟我么可以直接抛弃java语法树了吗。

出现了点小问题

这两天业务方实际在使用过程中,突然反馈说貌似我们接入的Hilt貌似不行啊,进入到页面直接崩溃了。

有一说一,一脸懵逼。先看看异常吧。初一开始我以为是kapt没有生成好或者别的什么原因导致的。

com.xxxxxx.xxxxxx}: java.lang.ClassCastException: xxxxx.DaggerHiltApplication_HiltComponents_SingletonC$ActivityRetainedCImpl$ActivityCImpl cannot be cast to xxxxx_GeneratedInjector

只能一步步调试咯,我打开项目开启编译项目,之后进入蛮长的等待过程中。10分钟过去了终于好了。

由于Hilt使用了kapt,所以很自然的打开了build/generated/source/kapt文件路径,之后我看了下DaggerHiltApplication_HiltComponents_SingletonC这个类的生成。

ActivityRetainedCImpl从这里我大概猜测出了一小部分Hilt原理,通过收集不同子Module的抽象接口,然后把这部分能力聚合在HiltApplication中,举个例子Hilt_BangumiDetailActivityV3这个就是一个子业务内的DI注入的一个类的实现。

突然这个时候我想到了一件事哦,也就是说我们的bundle-kapt模块,其实它的实际编译产物会根据接入业务的不同而产生实际的变更。也就是说虽然这个模块的代码没有发生变更,但是由于子业务增加了注解和代码变更,导致了这个模块的kapt还是需要重新执行,这样才能保证输出的产物是变化的。

然而我们的项目之前由于工程结构太庞大了,可能有30-40个Module,所有我们将一部分没有变更的代码产物化,也就是基于commit变成了一个个aar或者jar发布到了远端。之后根据commit来重新定向到产物。

而bundle-kapt这个模块也很不幸,被当做了一个静态模块,变成了一个远端的产物,之后即时业务添加了再多的注入相关的,因为bundle-kapt没有参与编译,所以注入的能力就出错了。

总结

我们团队算是一个比较好玩的团队了,团队有两位巨佬,一位大佬专门负责编译相关的,基本gradle方面都懂了,而且玩的也很花里胡哨的。另外一位大佬lancet作者,gradle方面懂得多就不提了,上一篇文章最后的问题也是这位大佬帮忙处理的。

而其他的组员其实人也都非常的不错,而且我们团队也做了很多东西。比如之前介绍的网络优化,资源混淆插件优化,图片中间件,动态化,自研的路由框架,还有blkv自研的ky存储框架等等。

同样的我们的kt版本还有agp版本都算是业内比较靠前的了。一方面是大佬能cover住,另一方面我们也会在这部分投入人力,我们也已经开始用viewbinding的代理啦

以上就是哔哩哔哩在Hilt组件化的使用技术探索的详细内容,更多关于哔哩哔哩Hilt组件化使用的资料请关注其它相关文章!


推荐阅读
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 如何搭建Java开发环境并开发WinCE项目
    本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 本文介绍了一个免费的asp.net控件,该控件具备数据显示、录入、更新、删除等功能。它比datagrid更易用、更实用,同时具备多种功能,例如属性设置、数据排序、字段类型格式化显示、密码字段支持、图像字段上传和生成缩略图等。此外,它还提供了数据验证、日期选择器、数字选择器等功能,以及防止注入攻击、非本页提交和自动分页技术等安全性和性能优化功能。最后,该控件还支持字段值合计和数据导出功能。总之,该控件功能强大且免费,适用于asp.net开发。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文总结了在开发中使用gulp时的一些技巧,包括如何使用gulp.dest自动创建目录、如何使用gulp.src复制具名路径的文件以及保留文件夹路径的方法等。同时介绍了使用base选项和通配符来保留文件夹路径的技巧,并提到了解决带文件夹的复制问题的方法,即使用gulp-flatten插件。 ... [详细]
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社区 版权所有