标签: Dagger

从 Dagger 到 Hilt,谷歌为何执着于让我们用依赖注入?

开始

说到依赖注入,做 Android 的人都会想到一个库:Dagger;说到 Dagger,大家的反应普遍是一套三连:牛逼、高端、我才不用。

又牛逼又高端,为什么不用?因为太难了。是吧?又难学又难用。大多数的人在学习 Dagger 的路上就被直接劝退了,剩下的这一小撮人*终排除万难,学会并且用上了 Dagger,但多半都是用着用着就掉进了自己亲手用 Dagger 搭建的迷宫里,怎么也绕不清楚,而且越陷越深,就这么成年累月地被它折磨。

有人可能会说:难用就别用呗?拆出来啊。

拆?哼哼。你对 Dagger 一无所知。

而就在上个月,Android 团队又在 Jetpack 里面又增加了一个新的依赖注入库:Hilt。这个 Hilt 是专门针对于 Android 平台的依赖注入库,它是基于 Dagger 的。

啊?基于……Dagger?这次到底是真正的神器到来,还是又一个大坑?

%title插图%num

依赖注入是什么?

Dagger 的名字取自有向无环图 DAG (directed acyclic graph):

%title插图%num

因为程序里的依赖关系拼接起来就是一个或者多个有向无环图:

%title插图%num

DAG-er,Dagger,取了个谐音,Dagger 是匕首的意思。而这次的 Hilt 是刀柄的意思,匕首很难用是吧?来,给你个柄。

说得很好听,到底有没有那么好用啊?这是个复杂的问题,且听我慢慢道来~

%title插图%num

依赖注入有什么用

Hilt 好不好用,我们先来看看它是个什么。它是个用注解来进行配置的依赖注入库。注解是它的写法,首先它是个依赖注入库,对吧?什么是依赖注入?一个类里有两个变量,这两个变量就是它的依赖:

%title插图%num

要初始化一个依赖,有两种方法:*,你这个类自己初始化:

%title插图%num

第二,让外部帮你初始化。

其中这第二种,让外部帮你初始化你的依赖,就叫依赖注入。关键在于初始化是谁做的,至于*后一步是你把结果拿过来,还是说你连拿都不用拿,*后一步的赋值工作也让外部来帮你做了,这都不重要,只要初始化工作是外部做的,就都叫依赖注入。

所以 Factory 的使用是依赖注入吗?

%title插图%num

是的。

Builder?

%title插图%num

也是。

带参数的构造函数?

%title插图%num

也是!

这些都属于由外部来提供依赖的初始化,所以都是依赖注入,并不是非要像 Dagger 那样使用注解的像魔法一样的才叫依赖注入。也就是说,其实我们每个人都已经在使用依赖注入了。虽然很多人在面对 Dagger 的时候会问「依赖注入到底有什么用」,但其实 Dagger 并不是提供了依赖注入的能力,而是为依赖注入提供了一种更简单的方式。依赖注入本来就是有用的,这个问题不想明白,不管是 Dagger 还是现在的 Hilt,你都用不好。

Dagger 让我们可以用注解的方式来配置依赖关系,让依赖注入变得更方便。不过由于功能复杂,导致它的上手非常困难;再加上刚才我说的,很多人对于依赖注入的作用以及 Dagger 的定位都没搞清楚,这两个原因加起来,就导致很多人还没学会 Dagger 就把它弃了,让 Dagger 成为 Android 史上*受冷落的优质库。这样的结果不论是对 Dagger 还是对我们,都是很可惜的。

而 Hilt 的出现,就直接解决了 Dagger 太复杂的这个问题。

%title插图%num

Hilt 怎么帮助我们进行依赖注入

Hilt 是 Google 专门针对 Android 平台做的一个依赖注入库。它不是从里到外全新开发的,而是基于 Dagger 做的,它的下层还是 Dagger。

为什么不直接去优化改进 Dagger,而要基于它做一个新库呢?因为 Hilt 做的事其实也并不是对 Dagger 进行优化,而是场景化:针对 Android 开发制定了一系列的规则,通过这些规则大大简化了这套工具的使用。例如在 Dagger 里,你要对某个类的依赖进行注入,你需要手动获取依赖图和执行注入依赖操作:

%title插图%num

而在 Hilt 里,注入会自动完成:

%title插图%num

因为 Hilt 会自动找到 Android 的系统组件里面那些*佳的初始化位置——比如 Activity 的 onCreate() ——然后在这些位置注入依赖。所以,为什么不是去优化 Dagger,而是做了个新库?因为 Hilt 本身并不是一种优化,而是场景化,或者说,它是一种针对场景的优化。总之,它是不通用的,只能给 Android 用,所以不能放在 Dagger 里。

有点明白了吧?

那它具体怎么用呢?大概是这样的:

我们程序里有些对象是全局共享的,比如线程池,或者 Retrofit 对象,这种东西我们通常会把它放在 Application 对象里,或者做成单例的:

%title插图%num

而如果用 Hilt,你也可以把它做成自动注入的依赖:

%title插图%num

还有些对象是局部共享的,比如某个 Activity 会把一些显示用的数据共享给它内部的一些 View 和 Fragment。这一类情况我们的做法通常是获取外部 Activity 对象然后强转,再去拿它内部的对象:

%title插图%num

而如果用 Hilt,你可以把这个对象直接声明出来,让它自动注入:

%title插图%num

这不只是一个「美观」的差别,依赖注入可以让你的程序更加灵活,比如如果你的 View 可以在多个不同的 Activity 里显示,那你在 View 里面要怎么强转?你要转成谁?

%title插图%num

很麻烦,是吧?而如果用依赖注入,这些就都是自动的。

除了共享的对象,不共享的也可以用依赖注入的方式来进行初始化,因为依赖注入的作用除了对共享对象提供一致性支持,也可以让我们在创建任何对象的时候省一些思考和力气:

  1. @Inject newUser: User

总之,如果一个组件可能会被被共享,或者不会被共享但可能会在多处使用,你都可以使用 Hilt 来把它配置成依赖注入的加载方式。

加载的方式可以选择直接调用构造函数:

%title插图%num

或者指定子类或实现类:

%title插图%num

或者干脆给出具体的代码:

%title插图%num

加载的作用域可以选择默认的每次都初始化,也可以设置成全局单例的:

%title插图%num

也可以设置成针对任何 Activity、Fragment、View 或者 ViewModel 的局部共享:

%title插图%num

简单又强大,好用又灵活。具体的写法你可以去看文档,或者过段时间我会有一次公开课,到时候也会提前通知大家。

到这里有的人可能会分个叉可能会想:诶 ButterKnife 或者现在 Jetpack 推出的 ViewBinding 它们提供的功能,Hilt 提供了吗?因为如果提供了,我在用了 Hilt 之后,不就可以把 ButterKnife 和 ViewBinding 扔掉了?

不好意思,Hilt 不提供它们的功能。Hilt 和 Dagger 虽然用法和 ButterKnife 很像,都是给变量加注解,然后变量会自动赋值,但它们的功能定位是不一样的:Hilt 和 Dagger 是做依赖注入的,而 ButterKnife 和 ViewBinding 是做视图绑定的。

这可不是个文字游戏,依赖注入和视图绑定是有本质区别的:依赖注入是由外部对对象进行初始化,也就是所谓的控制翻转;而视图绑定是让变量去指向一个已经有了的 View,它的依赖依然是由依赖持有者自己决定的,这是一个本质的区别。

%title插图%num

Dagger 为什么难用

这么看来,Hilt 还是很好用的,是吧?那有些人就又有问题了:哎,Hilt 这么好用,那Dagger 真的难用吗?到底难用在哪了?

其实说白了,Dagger 的难用主要在于这个框架太强大和灵活了,导致你要遵守很多约定才能正确使用它。比如在 Hilt 里,一个注解就能让 Activity 内部的依赖自动被注入,而 Dagger 需要手动注入;再比如在 Hilt 里如果你想让一个对象只在 Activity 内部被共享而不是全局共享,也就是一个注解能解决的问题,而在 Dagger 里面你需要先去创建一个自定义的注解。这些难吗?每个都不难的,对吧?但把它们放在一起,让你灵活搭配使用,就有点难了。

另外,Dagger 被大家普遍认为难的另一个原因刚才我也说过了:很多人连依赖注入都不太懂的。所以我再说一遍:如果一个组件可能被共享,或者可能在多处被使用,你可以使用依赖注入来初始化它。然后,在需要依赖注入的场景里,使用 Dagger 能让你的依赖注入写起来更简单。*后,Hilt 进一步简化了这个事情。先知道它是什么,再去用它。

Android Studio 4.1发布:可直接运行安卓模拟器、支持 Dagger 导航和 TensorFlow Lite 模型…

%title插图%num

近日,Android Studio 4.1 版本正式发布,今天我们很高兴地发布了稳定版的 Android Studio 4.1,其中包含针对常见的编辑、调试和优化用例的一系列特性。此版本的一大主题是帮助你在使用 Android Jetpack 库(这是 Android 的库套件,旨在帮助开发人员遵循*佳实践并更快地编写代码)时提高工作效率。根据大家的反馈,我们对代码编辑体验以及流行 Android 库的 IDE 集成做了许多改进。

Android Studio 4.1 的一些亮点包括用于查询应用数据库

 

的新数据库检查器(Database Inspector)、支持浏览使用 Dagger 或 Hilt 进行依赖项注入的项目,以及对 Android 设备中 TensorFlow Lite 模型的支持和对设备端机器学习的更好支持。我们还更新了 Apply Changes 以加快部署速度。根据大家的反馈,我们进行了一些更改,用新的原生内存剖析器和独立剖析工具来帮助游戏开发人员。

产品质量仍然是团队关注的重点,我们一直在努力追踪错误和性能问题。许多开发人员告诉我们,他们喜欢专注于提高性能和可靠性;因此我们很高兴地报告,在这个发行周期中我们修复了 2370 个错误,并关闭了 275 个开放问题。我们一直在努力保持高质量,因为我们知道这是提高开发人员工作效率的关键。

感谢那些在预览版本中提供了早期反馈的人们。你们的反馈意见帮助我们迭代和改进了 Android Studio 4.1 中的功能。如果你已经准备好使用下一个稳定版本,并且想要使用一套新的生产力特性,就请下载 Android Studio 4.1 吧。

以下是按主要开发流程排序的 Android Studio 4.1 中新特性的完整列表。

https://youtu.be/Yhbr6u7f3ME

设计

Material Design 组件更新

现在,create New Project 对话框中的 Android Studio 模板使用 Material Design Components(MDC),并且默认遵循更新的主题和样式指南。这些更改将使用户更容易使用推荐的 material 样式模式,并支持深色主题等现代 UI 特性。

%title插图%numProject Templates 中的 MDC 更新

更新包括:

  • MDC:项目依赖于 build.gradle 中的 com.google.android.material:material。基本应用主题使用 Theme.MaterialComponents.* 父级,并替换了更新后的 MDC 颜色和“on”属性。
  • 颜色资源:colors.xml 中的颜色资源使用字面名称(例如 purple_500 代替了 colorPrimary)。
  • 主题资源:主题资源位于 themes.xml(而非 styles.xml)中,并使用 Theme.名称。
  • 黑暗主题:基本应用主题使用 DayNight 父级,并拆分为 res/values 和 res/values-night。
  • 主题属性:颜色资源在布局和样式中以主题属性的形式(例如?attr/colorPrimary)引用,以避免硬编码颜色。

开发

数据库检查器

我们希望使用新的数据库检查器来简化检查、查询和修改应用数据库的过程。首先,将你的应用部署到运行 API 级别 26 或更高级别的设备,然后从菜单栏中选择 View>Tool Windows>Database Inspector。无论你的应用使用 Jetpack Room 库还是直接使用 SQLite 的 Android 平台版本,现在都可以轻松地检查正在运行的应用中的数据库和表,或运行自定义查询。

由于 Android Studio 在检查应用时会保持实时连接,因此你还可以使用数据库检查器修改值,并在运行的应用中查看这些更改。如果你使用 Room persistence 库,则 Android Studio 还会在代码编辑器中的每个查询旁边放置运行按钮,以帮助你快速运行在 @Query 注解中定义的查询。更多信息见 :

https://d.android.com/studio/inspect/database

%title插图%num使用数据库检查器检查、查询和修改应用的数据库

运行 Android 模拟器

现在,你可以直接在 Android Studio 中运行 Android 模拟器。使用此功能可以节省屏幕空间、使用热键在模拟器和编辑器窗口之间快速导航,以及在单个应用窗口中组织 IDE 和模拟器工作流。你可以在 Studio 中管理快照和常见的模拟器操作,例如旋转和获取屏幕截图,但是要访问全部选项,仍然需要运行稳定的模拟器。你可以转到 File→Settings→Tools→Emulator→Launch in Tool Window 来选用此功能。

%title插图%num在 Android Studio 中运行 Android 模拟器

Dagger 导航支持

Dagger 是 Android 上用于依赖项注入的流行库。Android Studio 提供了新的边线操作,并扩展了 Find Usages 窗口中的支持,使用户更容易地浏览 Dagger 相关的代码。例如,单击使用给定类型的方法旁边的

%title插图%num

边线操作,会将你导航到该类型的提供方。相反,单击

%title插图%num

边线操作会将你导航到将类型用作依赖项的位置。Android Studio 还支持通过 Jetpack Hilt 库定义的依赖项的导航操作。更多信息见:

https://developer.android.com/studio/releases#dagger-navigation

%title插图%num使用边线操作浏览与 Dagger 相关的代码

使用 TensorFlow Lite 模型

Android 开发人员正在使用机器学习来创造创新和有用的体验。TensorFlow Lite 是一个流行的,用于编写移动机器学习模型的库,我们希望让它更容易将这些模型导入 Android 应用。与视图绑定类似,Android Studio 生成易于使用的类,让你可以用更少的代码和更好的类型安全性来运行模型。ML 模型绑定的当前实现支持图像分类和风格迁移模型,前提是它们通过元数据得到了增强。

要查看导入模型的详细信息并获得有关如何在应用中使用它的说明,请在项目中双击.tflite 模型文件以打开模型查看器页面。更多信息见:

https://developer.android.com/studio/write/mlmodelbinding

%title插图%num在 Android Studio 4.1 中查看 TensorFlow Lite 模型元数据

构建和测试

Android 模拟器——可折叠设备支持

Android Studio

除了*近添加了 5G 蜂窝测试支持外,我们还在 Android 模拟器中添加了可折叠设备支持。使用 Android 模拟器 30.0.26 及更高版本,你可以配置具有多种折叠设计和配置的可折叠设备。配置可折叠设备后,模拟器将发布铰链角度传感器更新和形态变化,因此你可以测试你的应用如何响应这些形状因素。更多信息见:

https://medium.com/androiddevelopers/developing-for-android-11-with-the-android-emulator-a9486af2d7ef

%title插图%num

Apply Changes 更新

更快的构建可帮助开发人员更轻松、更快速地更改其应用。为了在你迭代应用时提高工作效率,我们对运行 Android 11 或更高版本设备的 Apply Changes 进行了多项增强。

我们在优化迭代速度方面投入大量资源,开发了一种无需安装应用即可在设备上部署和保留更改的方法。初始部署后,使用 Apply Code Changes 或 Apply Changes and Restart Activity 后续部署到 Android 11 设备的速度现在有了显著提高。我们还在 Apply Changes 中添加了对额外代码更改的支持。现在,如果你添加了一个方法,可以单击 Apply Code Changes 或 Apply Changes and Restart Activity 将这些更改部署到正在运行的应用。

从 AAR 导出 C/C++ 依赖项

Android Gradle Plugin4.0 添加了在 AAR 依赖项中导入 Prefab 包的功能。我们希望扩展此功能的能力,以支持共享原生库。AGP 版本 4.1 支持从 Android 库项目的 AAR 中的外部原生构建导出库。要导出原生库,请将以下内容添加到库项目的 build.gradle 文件的 android 代码块中:

  1. buildFeatures {
  2.     prefabPublishing true
  3. }
  4. prefab {
  5.     mylibrary {
  6.       headers “src/main/cpp/mylibrary/include”
  7.     }
  8.     myotherlibrary {
  9.         headers “src/main/cpp/myotherlibrary/include”
  10.     }
  11. }

原生崩溃报告的符号化解析

当原生代码中发生崩溃或 ANR 时,系统会生成堆栈轨迹,这是你的程序在崩溃之前调用过的嵌套函数序列的快照。这些快照可帮助你找出并修正源代码中的任何问题,但必须先对其进行符号化解析,以将机器地址转换回简单易懂的函数名称。

如果你的应用或游戏是使用原生代码(如 C++)开发的,那么你现在可以针对应用的每个版本向 Play 管理中心上传调试符号文件。Play 管理中心会使用这些调试符号文件对应用的堆栈轨迹进行符号化解析,以便你更轻松地分析崩溃和 ANR。要将调试符号包含在你的应用包中,请将以下代码行添加到项目的 build.gradle 文件中:

android.buildTypes.release.ndk.debugSymbolLevel = 'SYMBOL_TABLE'

优化

System Trace UI 改进

在 Android Studio 4.1 中,我们对 System Trace 进行了全面改革。这是一种优化工具,可让你实时查看你的应用使用系统资源的情况。通过边框选择模式,我们可以更轻松地选择跟踪;我们还添加了新的分析标签,并添加了更多的帧渲染数据,以帮助你调查应用 UI 中的渲染问题。更多信息见:

https://medium.com/androiddevelopers/whats-new-in-android-studio-system-trace-5841465c5935

边框选择:在 Threads 部分中,现在你可以拖动鼠标选出一个矩形区域,然后可以点击区域右上角的 Zoom to Selection 按钮(或使用键盘快捷键 M)放大选中区域。当你将相似的线程拖放到一起时,可以选择多个线程以同时检查所有这些线程。

使用边框选择可以更轻松地选择跟踪。

%title插图%num

Summary 标签页: Analysis 面板中新增的 Summary 标签页显示以下内容:

  • 特定事件所有发生实例的汇总统计信息,例如发生次数和*短 / *长持续时间。
  • 所选发生实例的跟踪事件统计信息。
  • 有关线程状态分布的数据。
  • 所选跟踪事件中运行时间*长的发生实例。

%title插图%num在 Summary 标签页中查看汇总的统计信息

显示数据:在 Display 部分,Surface Flinger 和 VSYNC 的新时间线可帮助你调查应用 UI 中的渲染问题。

独立性能剖析器

现在可以在独立于 Android Studio 主窗口的单独窗口中使用 Android Studio 性能剖析器。在优化使用其他工具(如 Unity 或 Visual Studio)构建的 Android 游戏时,此功能很有用。

要运行独立性能剖析器,请执行以下操作:

1、确保你的系统上尚未运行 Android Studio 性能剖析器。

2、转到安装目录并转到 bin 目录:

  • Windows/Linux:<studio-installation-folder>\bin
  • macOS:<studio-installation-folder>/Contents/bin

3、根据你的操作系统,运行 profiler.exe 或 profiler.sh

独立性能剖析器允许你连接到 Android 模拟器或任何连接的设备。

%title插图%num使用独立的 Android Studio 性能剖析器优化你的应用

原生内存剖析器

对于游戏开发人员和其他使用 C++ 的开发人员来说,要了解如何优化其应用的内存使用情况,就一定要跟踪原生内存使用情况。Android Studio Memory Profiler 现在包括一个 Native Memory Profiler,用于部署到运行 Android 10 或更高版本物理设备的应用。这个原生内存剖析器会跟踪特定时间段内原生代码中对象的分配 / 取消分配,并提供有关总分配和剩余系统堆大小的信息。关注公众号 逆锋起笔,回复 pdf,下载你需要的各种学习资料。

要启动记录过程,请单击 Memory Profiler 窗口顶部的 Record native allocations:

%title插图%num使用原生内存剖析器查看原生内存分配

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速