【Android Jetpack】Hilt 依赖注入框架

文章目录

    • 依赖注入
    • Dagger
    • Hilt
    • Koin
    • 添加依赖项
    • Hilt常用注解的含义
      • @HiltAndroidApp
      • @AndroidEntryPoint
      • @Inject
      • @Module
      • @InstallIn
      • @Provides
      • @EntryPoint
    • Hilt组件生命周期和作用域
    • 如何使用 Hilt 进行依赖注入

依赖注入

依赖注入是一种软件设计模式,它允许客户端从外部源获取其依赖项,而不是自己创建它们。它是一种用于在对象及其依赖项之间实现控制反转 (IoC) 的技术。

在安卓开发中,依赖注入(Dependency Injection,简称DI)是一种设计模式,用于解耦组件之间的依赖关系。它的基本思想是将对象的依赖关系从代码中移除,而是通过外部容器来管理和注入这些依赖。

传统的方式是在类内部直接创建和管理依赖对象,这样容易导致代码的耦合性增加,难以进行单元测试和代码重用。而依赖注入通过将依赖的创建和管理交给外部容器,使得类只关注自身的逻辑,而不需要关心依赖对象的创建和维护。

Dagger

Dagger是一个Java和Android平台上的依赖注入框架,由Google开发和维护。它的目标是简化管理对象之间的依赖关系,提高代码的可测试性、可扩展性和可维护性。

Dagger基于Java的注解处理器和反射机制,通过在编译时生成依赖注入代码,而不是在运行时进行反射。这种方式具有更好的性能和类型安全性,并且可以在编译时检测到一些错误,提供更好的开发体验。

Dagger是匕首的意思,依赖注入就好像是把匕首直接插入了需要注入的地方,直击要害。

Hilt

Hilt是刀把的意思,它把匕首最锋利的地方隐藏了起来,因为如果你用不好匕首的话反而可能会误伤自己。Hilt给你提供了一个安稳的把手,确保你可以安全简单地使用。

Android团队在Jetpack中增加了HiltHilt是基于Dagger的一个高级封装,旨在简化在Android应用中使用Dagger进行依赖注入的过程。Hilt提供了一套注解和工具,使得使用Dagger更加便捷和易于理解,并且提供了一些默认的配置,以减少开发者的配置工作量。并且得到了 Android Studio 的支持。

Hilt做的优化包括:

  1. 无需编写大量的Component代码
  2. Scope也会与Component自动绑定
  3. 预定义绑定,例如Application和Activity
  4. 预定义的限定符,例如@ApplicationContext@ActivityContext

类似于Room等jetpack,利用注解功能简化了很多复杂的程序。

Hilt的核心思想仍然是依赖注入,它遵循了Dagger的注入原理和组件机制。Hilt的组件体系与Dagger类似,包括ApplicationComponent、ActivityComponent、FragmentComponent等,每个组件都有自己的生命周期和作用域。开发者可以使用Hilt的注解来标记和配置这些组件,以及在需要注入依赖的地方使用相应的注解

Koin

Koin - a smart Kotlin injection library to keep you focused on your app, not on your tools

Koin是为Kotlin开发者提供的一个实用型轻量级依赖注入框架,采用纯 Kotlin 语言编写而成,仅使用功能解析,无代理、无代码生成、无反射。

Hilt、Dagger、Koin等等都是依赖注入库,Google也在努力不断的完善依赖注入库从Dagger到Dagger2在到现在的Hilt,因为依赖注入是面向对象设计中最好的架构模式之一,使用依赖注入库有以下优点:

  • 依赖注入库会自动释放不再使用的对象,减少资源的过度使用。
  • 在配置scopes范围内,可重用依赖项和创建的实例,提高代码的可重用性,减少了很多模板代码。
  • 代码变得更具可读性。
  • 易于构建对象。
  • 编写低耦合代码,更容易测试。

添加依赖项

首先,将 hilt-android-gradle-plugin 插件添加到项目的根级 build.gradle 文件中:

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

然后,应用 Gradle 插件并在 app/build.gradle 文件中添加以下依赖项:

...
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'android {...
}dependencies {implementation "com.google.dagger:hilt-android:2.28-alpha"kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
}

Hilt常用注解的含义

Hilt常用注解包含@HiltAndroidApp@AndroidEntryPoint@Inject@Module@InstallIn@Provides@EntryPoint等等。

@HiltAndroidApp

  1. 所有使用Hilt的App必须包含一个使用@HiltAndroidApp注解的Application。它会替代Dagger中的AppComponent。
  2. @HiltAndroidApp注解将会触发Hilt代码的生成,作为应用程序依赖项容器的基类。
  3. 生成的Hilt组件依附于Application的生命周期,它也是App的父组件,提供其他组件访问的依赖。
  4. 在Application中设置好@HiltAndroidApp之后,就可以使用Hilt提供的组件了,组件包含Application、Activity、Fragment、View、Service、BroadcastReceiver 等等。

@AndroidEntryPoint

Hilt提供的@AndroidEntryPoint注解用于提供Android类的依赖(Activity、Fragment、View、Service、BroadcastReceiver)。

  • Activity:仅仅支持ComponentActivity的子类例如FragmentActivity、AppCompatActivity等等。
  • Fragment:仅仅支持继承androidx.Fragment的Fragment
  • View
  • Service
  • BroadcastReceiver

如果您使用@AndroidEntryPoint为某个Android类添加注释,则还必须为依赖于该类的Android类添加注释。例如,如果您为某个Fragment添加注释,则还必须为使用该Fragment的所有Activity添加注释。

@Inject

Hilt需要知道如何从相应的组件中提供必要依赖的实例。使用@Inject注解来告诉Hilt如何提供该类的实例,它常用于构造函数、非私有字段、方法中。

注意:在构建时,Hilt为Android类生成Dagger组件。然后Dagger遍历您的代码并执行以下步骤:

  • 构建并验证依赖关系,确保没有未满足的依赖关系。
  • 生成它在运行时用于创建实际对象及其依赖项的类。
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {@Inject lateinit var analytics: AnalyticsAdapter...
}

注意:由Hilt注入的字段不能为私有字段。尝试使用Hilt注入私有字段会导致编译错误。

@Module

有时,类型不能通过构造函数注入。发生这种情况可能有多种原因。例如,您不能通过构造函数注入接口。此外,您也不能通过构造函数注入不归您所有的类型,如来自外部库的类。在这些情况下,您可以使用Hilt模块向Hilt提供绑定信息。

Hilt模块是一个带有@Module注释的类。与Dagger 模块一样,它会告知Hilt如何提供某些类型的实例。与Dagger 模块不同的是,您必须使用@InstallIn为Hilt模块添加注释,以告知Hilt每个模块将用在或安装在哪个Android类中。

常用于创建依赖类的对象(例如第三方库 OkHttp、Retrofit等等),使用@Module注解的类,需要使用@InstallIn注解指定module的范围。

@Module
@InstallIn(ApplicationComponent::class)
// 这里使用了 ApplicationComponent,因此 NetworkModule 绑定到 Application 的生命周期。
object NetworkModule {
}

@InstallIn

使用@Module注入的类,需要使用@InstallIn注解指定module的范围,例如使用 @InstallIn(ActivityComponent::class) 注解的module会绑定到activity的生命周期上。

Hilt提供了以下组件来绑定依赖与对应的Android类的活动范围。

Hilt 提供的组件对应的 Android 类的活动范围
ApplicationComponentApplication
ActivityRetainedComponentViewModel
ActivityComponentActivity
FragmentComponentFragment
ViewComponentView
ViewWithFragmentComponentView annotated with @WithFragmentBindings
ServiceComponentService

注意:Hilt没有为broadcast receivers提供组件,因为Hilt直接从ApplicationComponent注入broadcast receivers。

@Provides

它常用于被@Module注解标记类的内部的方法,并提供依赖项对象。

@Module
@InstallIn(ApplicationComponent::class)
// 这里使用了 ApplicationComponent,因此 NetworkModule 绑定到 Application 的生命周期。
object NetworkModule {/*** @Provides 常用于被 @Module 注解标记类的内部的方法,并提供依赖项对象。* @Singleton 提供单例*/@Provides@Singletonfun provideOkHttpClient(): OkHttpClient {return OkHttpClient.Builder().build()}
}

@EntryPoint

Hilt支持最常见的Android类Application、Activity、Fragment、View、Service、BroadcastReceiver等等,但是您可能需要在Hilt不支持的类中执行依赖注入,在这种情况下可以使用@EntryPoint注解进行创建,Hilt会提供相应的依赖。

Hilt组件生命周期和作用域

image-20231114001440012

image-20231114001540141

如何使用 Hilt 进行依赖注入

我们先来看一个简单的例子,注入HiltSimple并在Application中调用它的方法。

class HiltSimple @Inject constructor() {fun test1() {Log.e(TAG, "已经创建成功 ")}
}@HiltAndroidApp
class HiltApplication : Application() {@Injectlateinit var mHiltSimple: HiltSimpleoverride fun onCreate() {super.onCreate()mHiltSimple.doSomething()}
}

Hilt需要知道如何从相应的组件中提供必要依赖的实例。使用@Inject注解来告诉Hilt如何提供该类的实例,@Inject常用于构造函数、非私有字段、方法中。

  • 可参考Jetpack新成员,一篇文章带你玩转Hilt和依赖注入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/180516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能井盖传感器怎么监测井盖倾斜?

城市道路上的井盖是常见的安全隐患,由于井盖质量不过关、安装不合理等原因导致的井盖位移或倾斜等事故,每年都处于不断增加的状态。为了减少此类案件的发生并维护社会治安,国家相关部门已经制定了多项政策法规对井盖进行统一监管。鼓励各个城…

有哪些不错的golang开源项目?

前言 下面是github上的golang项目,适合练手,可以自己选择一些项目去练习,整理不易,希望能多多点赞收藏一下!废话少说,我们直接进入正题>>> 先推荐几个教程性质的项目(用于新手学习、…

C Primer Plus讲解前置说明

说明 本来是准备接着写下去,写着就发现思路整理的有点杂乱无章。果然是“想一千次,不如去做一次”。所以这次准备基于《C Primer Plus》第六版给大家分享一下,也是自己梳理的一个过程。有关C语言的书很多,我选这本也恰巧是因为以前…

Django二转Day02

http #1 http 是什么#2 http特点#3 请求协议详情 -请求首行---》请求方式,请求地址,请求协议版本 -请求头---》key:value形式 -referer:上一次访问的地址 -user-agenet:客户端类型 -name&#x…

面试题:汉诺塔问题 · 递归

你好,我是安然无虞。 文章目录 汉诺塔问题问题描述解题思路代码详解 汉诺塔问题 问题描述 解题思路 这道题的名字还是很响的,基本上都能看出来使用递归解题,但是具体怎么实现还是需要细细想一想。 我们一步一步来,请看&#xff…

2023-11-28 LeetCode每日一题(设计前中后队列)

2023-11-28每日一题 一、题目编号 1760.设计前中后队列二、题目链接 点击跳转到题目位置 三、题目描述 请你设计一个队列,支持在前,中,后三个位置的 push 和 pop 操作。 请你完成 FrontMiddleBack 类: FrontMiddleBack() 初…

微服务实战系列之Cache

前言 欢迎来到Cache(缓存)的世界! 自从世界第一台计算机诞生之日起,人们对效率的渴望逐步增强。从CPU到存储,从芯片到内存,一批又一批的先驱以一种孜孜不倦的“工匠”精神,为计算机运行效率的提…

揭开 BFC 的神秘面纱:前端开发必知必会

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

用Sublime编写Lua脚本

大家好,我是阿赵。   现在很多手游项目使用lua作为热更新的代码脚本,我一直很喜欢用Sublime来写lua程序。喜欢使用它的原因是它的轻量化,因为我经常要同时打开多个项目,Unity和VisualStudio这些软件都比较占用电脑的性能&#x…

Nodejs+vue基于微信小程序的高校餐厅食品留样管理系统uniapp

任何系统都要遵循系统设计的基本流程,本系统也不例外,同样需要经过市场调研,需求分析,概要设计,详细设计,编码,测试这些步骤,基于nodejs小程序技术设计并实现了小程序。采用B/S结构,…

父进程隐藏——ConsoleApplication903项目

首先我发现用calc来做进程隐藏实验是失败的,父进程一直都是svhost.exe 那么我用我自己生成的cs木马beacon903.exe试试 试试explorer.exe 再试试cmd.exe 可以看到成功变成cmd.exe 可以看到我们可以通过这种方式虚假父进程 以上我们是直接获得的pid,那…

微信小程序+中草药分类+爬虫+keras

目录 1 介绍2 数据爬虫3 模型训练和验证3.1 模型训练3.2 导入一张图片进行验证 4 后台flask部署5 微信小程序 1 介绍 本项目使用深度学习模型,训练5种中药材数据集,然后将其集成到微信小程序,通过微信小程序拍照,将图片传输给后端…

MIT_线性代数笔记:第 08 讲 求解 Ax=b:可解性与结构

目录 可解的条件 Solvability conditions on b特解 A particular solution通解 Complete solution与零空间进行线性组合 Combined with nullspace 秩 Rank 可解的条件 Solvability conditions on b 矩阵 A 的第三行为第一行和第二行的加和,因此 Axb 中 b 的第 3 个分…

海翔云平台 getylist_login.do SQL 注入漏洞复现

0x01 产品简介 海翔云平台一站式整体解决方案提供商,业务涵盖 批发、连锁、零售行业ERP解决方案、wms仓储解决方案、电商、外勤、移动终端(PDA、APP、小程序)解决方案。 0x02 漏洞概述 海翔云平台getylist_login.do接口处存在SQL注入漏洞&am…

SVG图片选择库组件封装及使用

需求 需求: 在项目中通常需要做菜单管理,想要让左侧菜单好看一点,一般都会选择添加图标,需要自定义选择喜欢的图标,得提供一个有选择项的图标库 延伸需求:在项目中通常可能有好几个图标选择库,可…

CentOS 系列:CentOS 7文件系统的组成

CentOS 7文件系统的组成 文件系统的组成Linux的一些重要目录文件和目录名主机名文件权限绝对路径和相对路径绝对路径相对路径 文件系统的组成 一切从根开始 文件路径中只有第一个/是根目录,后面的/是分隔符 文件名区分大小写 除斜线(/)以外,其他的字符…

ruoyi-plus使用Statistic统计组件升级element-plus

原本使用的就是gitee上lionli的ruoyi-plus版本的代码。但是在使用过程中作首页数据看板时想使用elementui的Statistic统计组件。结果在浏览器控制台报错找不到组件el-statistic 于是查看elementui的历史版本,发现是在新版中才有这个组件,旧版本是没这个组…

高防CDN可以起到什么作用?

高防CDN相对于普通的CDN加速,除了具备基础的加速功效外,高防CDN在每一节点上均有相应配置的防御功效,不仅具备了隐藏源站不被攻击的优势,也具备了访问加速,多节点防御的功效。随着互联网的不断发展,网络上的…

【运维】hive 高可用详解: Hive MetaStore HA、hive server HA原理详解;hive高可用实现

文章目录 一. hive高可用原理说明1. Hive MetaStore HA2. hive server HA 二. hive高可用实现1. 配置2. beeline链接测试3. zookeeper相关操作 一. hive高可用原理说明 1. Hive MetaStore HA Hive元数据存储在MetaStore中,包括表的定义、分区、表的属性等信息。 hi…

前端面试灵魂提问

1.自我介绍 2.在实习中,你负责那一模块 3.any与unknow的异同 相同点:any和unkonwn 可以接受任何值 不同点:any会丢掉类型限制,可以用any 类型的变量随意做任何事情。unknown 变量会强制执行类型检查,所以在使用一个…