Android Hilt依赖注入的使用讲解

目录
  • 什么是依赖注入
  • 使用依赖注入的好处
  • Hilt中常用的预定义限定符
    • @HiltAndroidApp
    • @AndroidEntryPoint
    • @Module
    • @InstallIn
    • @Provides
    • @Inject
    • @HiltViewModel
  • Hilt的使用
    • 依赖
    • 建立实体类
    • 添加Hilt入口
    • 提供对象
    • 获取对象
  • 应用与ViewModel中
    • 使用
  • 总结

什么是依赖注入

首先,某个类的成员变量称为依赖,如若此变量想要实例化引用其类的方法,可以通过构造函数传参或者通过某个方法获取对象,此等通过外部方法获取对象实例的称为依赖注入;而依赖注入又可以简单分为手动注入和自动注入两种方式;Hilt就是基于Dagger进行场景化优化的一个依赖注入库,Hilt是Google专门为Android平台打造的一个依赖注入库,在使用上极大程度进行啦简化(与dagger相比)

使用依赖注入的好处

Google文档中介绍的优势如下:

  • 重用代码
  • 易于重构
  • 易于测试

简单来说,在开发中某些内容需要进行层层手动调用,而且需要手动进行实例化;对于Hilt而言,它可以自动进行依赖注入,并且为项目中的每个 Android 类提供容器并自动管理其生命周期;某些需要全局使用的数据,可以通过Hilt进行共享,从而简化代码

Hilt中常用的预定义限定符

@HiltAndroidApp

所有使用 Hilt 的应用都必须包含一个带有 @HiltAndroidApp 注解的 Application 类。@HiltAndroidApp 会触发 Hilt 的代码生成操作,生成的代码包括应用的一个基类,该基类充当应用级依赖项容器,记得此Application类要在清单文件中进行引用

@HiltAndroidApp
class App : Application() { ... }

@AndroidEntryPoint

如果某个Activity要使用Hilt依赖注入,就必须给Activity添加@AndroidEntryPoint注解,同理Activity中的某个Fragment也需要使用,也必须添加@AndroidEntryPoint注解

目前Hilt 支持以下 Android 类:

  • Application(通过使用 @HiltAndroidApp)
  • ViewModel(通过使用 @HiltViewModel)
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver
@AndroidEntryPoint
class MainActivity : ComponentActivity() {...}

@Module

Hilt带有一个模块的类,使用@Module注解的类,它会告知Hilt,它提供了哪些实例,通常和@Provider搭配使用,必须通过@InstallIn注解为其添加作用域

@InstallIn

对于您可以从中执行字段注入的每个 Android 类,都有一个关联的 Hilt 组件,您可以在 @InstallIn 注解中引用该组件。每个 Hilt 组件负责将其绑定注入相应的 Android 类。

Android 组件 默认绑定
SingletonComponent Application
ActivityRetainedComponent Application
ViewModelComponent SavedStateHandle
ActivityComponent Application 和 Activity
FragmentComponent Application、Activity 和 Fragment
ViewComponent Application、Activity 和 View
ViewWithFragmentComponent Application、Activity、Fragment 和 View
ServiceComponent Application 和 Service
@Module
@InstallIn(SingletonComponent::class)
object AppModule {...}

@Provides

如果想要让Hilt知道,提供了哪些实例对象,可以使用@Provides进行注解,以下提供啦一个数据库实例,并且作用域是全局单例

    @Provides
    @Singleton
    fun providerAccountBean():AccountBean{
        return AccountBean("FranzLiszt","123456")
    }

@Inject

如果想要使用Hilt自动进行啦依赖注入的对象,可以使用@Inject注解进行调用;如下,无需进行实例化,它会自动引用providerAccountBean()提供的对象

@Inject lateinit var bean: AccountBean

@HiltViewModel

通过名称就可以了解,它需要与ViewModel类联合使用,作用于ViewModel上;如下,与@Inject结合使用,在构造函数引用啦上述Hilt提供的对象

@HiltViewModel
class AccountViewModel @Inject constructor(private val bean: AccountBean):ViewModel() {...}

Hilt的使用

依赖

第一步:在project/build.gradle中添加如下代码

plugins {
    ...
    id 'com.google.dagger.hilt.android' version '2.44' apply false
}

第二步:在app/build.gradle中添加如下代码

plugins {
    ...
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

第三步:在app/build.gradle中添加如下代码

//Dagger - Hilt
    implementation("com.google.dagger:hilt-android:2.44")
    kapt("com.google.dagger:hilt-android-compiler:2.44")

// Compose dependencies
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0-beta01"
    implementation "androidx.hilt:hilt-navigation-compose:1.0.0-alpha03"

第四步:在app/build.gradle中添加如下代码

android{
...
 compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

建立实体类

data class AccountBean(var username:String,var password:String)

添加Hilt入口

@HiltAndroidApp
class APP:Application() {}

提供对象

此处作为用例,只是简单写一个测试用例,在函数中可以编写复杂的程序,并不会影响程序性能,在程序初始化编译时会耗时一丢丢。一下提供啦单例AccountBean对象

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Provides
    @Singleton
    fun providerAccountBean():AccountBean{
        return AccountBean("FranzLiszt","123456")
    }
}

获取对象

给Activity添加HiltAndroidEntryPoint注解,然后可以通过Inject注解获取上面providerAccountBean方法提供的对象

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    @Inject lateinit var bean: AccountBean
    ...
    }

然后就可以直接进行对象引用

  @Composable
    fun showAccountInfo() {
        Column(
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = bean.username)
            Spacer(modifier = Modifier.height(20.dp))
            Text(text = bean.password)
        }
    }

应用与ViewModel中

在ViewModel中使用HiltViewModel注解,然后就可以使用Inject注解获取Hilt自动注入依赖的对象

@HiltViewModel
class AccountViewModel @Inject constructor(private val bean: AccountBean):ViewModel() {...}

定义两个具有状态的成员变量,其中AccountState是一个数据类,具有text和hint两个成员变量

private val _usernameState = mutableStateOf(AccountState(
        hint = "input username"
    ))
    val usernameState:State<AccountState> = _usernameState
    private val _passwordState = mutableStateOf(AccountState(
        hint = "input password"
    ))
    val passwordState:State<AccountState> = _passwordState

在ViewModel初始化函数中,将Hilt提供的对象的值赋值给VM中的两个状态变量

init {
        _usernameState.value = usernameState.value.copy(text = bean.username)
        _passwordState.value = passwordState.value.copy(text = bean.password)
    }

通过外部事件进行对应处理,外部输入框不断进行值修改,此处同步给VM中的状态变量

   fun onEvent(event: AccountEvent){
        when(event){
            is AccountEvent.ChangeUsername ->{
                _usernameState.value = usernameState.value.copy(text = event.value)
            }
            is AccountEvent.ChangePassword ->{
                _passwordState.value = passwordState.value.copy(text = event.value)
            }
        }
    }

使用

此处直接获取ViewModel的两个成员变量值,然后与两个输入框进行绑定,通过监听输入框的onValueChange方法,当其值不断修改时,然后调用VM中的onEvent方法,然后修改VM中的状态内容,由于输入框绑定了VM的状态变量,然后状态变量值改变后,相对应的UI界面会进行重组

    @Composable
    fun showAccountInfo (viewModel: AccountViewModel = hiltViewModel()){
        val username = viewModel.usernameState.value
        val password = viewModel.passwordState.value
        Column(
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            TextField(
                value = username.text,
                placeholder = { Text(text = username.hint)},
                onValueChange = {
                    viewModel.onEvent(AccountEvent.ChangeUsername(it))
                }
            )
            Spacer(modifier = Modifier.height(20.dp))
            TextField(
                value = password.text,
                placeholder = { Text(text = password.hint)},
                onValueChange = {
                    viewModel.onEvent(AccountEvent.ChangePassword(it))
                }
            )
        }
    }

总结

上述的俩个测例,只是使用Hilt提供的便利的冰山一角;Hilt使用起来很方便,而去可以提高代码结构,省去不必要的代码;其中Koin依赖注入库也备受好评,虽然我没有使用过,因为Google推Hilt,就首先入手啦;在性能上,我看了一些其他文章上介绍,大差不差的,所有根据自己需要进行选择。

到此这篇关于Android Hilt依赖注入的使用讲解的文章就介绍到这了,更多相关Android Hilt依赖注入内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一文吃透Hilt自定义与跨壁垒

    目录 前言 跨越 IOC容器的壁垒 使用EntryPoint跨越IOC容器壁垒 自定义Scope.Component Scope.Component.Module的真实含义 自定义 定义Scope 定义Component 使用Manager管理Component 在生命周期范围更小的Component中使用 解决独立library的依赖初始化问题 使用hilt的聚合能力解决问题 聚合能力+EntryPoint 问题衍生 末 前言 本文隶属于我归纳整理的Android知识体系的第四部分,属于DI中

  • Android Hilt Retrofit Paging3使用实例

    目录 效果视频 简述 Hilt+Retrofit 访问接口 网络实例 PagingSource ViewModel View 效果视频 简述 本Demo采用Hilt+Retrofit+Paging3完成,主要为了演示paging3分页功能的使用,下列为Demo所需要的相关依赖 //retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:conver

  • 移动端开发之Jetpack Hilt技术实现解耦

    目录 Hilt是什么 Hilt使用地方 依赖注入(DI)概念 Hilt使用 导入 Hilt是什么 Hilt 是基于 Dagger2 的针对 Android场景定制化 的框架. 这有点像什么? RxAndroid 是 RxJava 的Android平台定制化扩展.Andorid虽然由Java.Kotlin构成,但是它有很多平台的特性,比如它有 Java开发 所不知道的 Context 等. Dagger框架虽然很出名,在国外也很流行,但是在国内使用其的App少之又少,列举一些缺点: 上手难,众多A

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

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

  • Android Hilt的使用以及遇到的问题

    目录 简介 导入Hilt 组件层次 组件默认绑定 简单使用 @HiltAndroidApp 介绍 使用 @AndroidEntryPoint 介绍 使用 @Module 和 @InstallIn 介绍 使用 @Provides 和 @Binds 介绍 使用 @HiltViewModel 介绍 使用 @EntryPoint 介绍 小结 简介 Hilt 提供了一种将Dagger 依赖注入到Android 应用程序的标准方法.为Android 应用程序简化提供一组标准的.简化设置.可以读的组件:且为不

  • Android Hilt依赖注入的使用讲解

    目录 什么是依赖注入 使用依赖注入的好处 Hilt中常用的预定义限定符 @HiltAndroidApp @AndroidEntryPoint @Module @InstallIn @Provides @Inject @HiltViewModel Hilt的使用 依赖 建立实体类 添加Hilt入口 提供对象 获取对象 应用与ViewModel中 使用 总结 什么是依赖注入 首先,某个类的成员变量称为依赖,如若此变量想要实例化引用其类的方法,可以通过构造函数传参或者通过某个方法获取对象,此等通过外部

  • Android ButterKnife依赖注入框架使用教程

    目录 简介 APT整个流程 ButterKnife的工作原理 简介 BuffterKnife 采用 注解+ APT技术 APT:Annotation Processor tool 注解处理器,是javac的一个工具,每个处理器都是继承于AbstractProcessor 注解处理器是运行在自己的java虚拟机中 APT如何生成字节码文件: Annotation Processing 不能加入或删除java方法 APT整个流程 声明的注解等待生命周期为CLASS 继承AbstractProcess

  • 实例讲解Java的Spring框架中的控制反转和依赖注入

    近来总是接触到 IoC(Inversion of Control,控制反转).DI(Dependency Injection,依赖注入)等编程原则或者模式,而这些是著名 Java 框架 Spring.Struts 等的核心所在.针对此查了 Wikipedia 中各个条目,并从图书馆借来相关书籍,阅读后有些理解,现结合书中的讲解以及自己的加工整理如下: eg1 问题描述: 开发一个能够按照不同要求生成Excel或 PDF 格式的报表的系统,例如日报表.月报表等等.   解决方案: 根据"面向接口编

  • Dagger2 Android依赖注入学习笔记

    前言 最近在用 MVP + RxJava + Retrofit 写项目,觉得相对于其他的开发框架,这的确是给我们带来了很多方便,但是在网上搜寻相关资料的时候,总是能看到 MVP + RxJava + Retrofit + Dagger 这样的搭配组合,那 Dagger 又是一个怎样的框架呢,我也去具体搜了搜,但看到一些文章带着"Dagger2从入门到放弃"这样意思的句子,就感觉Dagger2会很难吗,emmmm...行吧,好像是有点难理解,但是想着既然有那么多人用这个框架,必然有它的好

  • 深入浅出讲解Spring框架中依赖注入与控制反转及应用

    目录 一. 概念: 1. 使用前: 2. 使用后: 二. 理解控制反转(Ioc): 三. IoC的应用方法 一. 概念: 依赖注入(Dependency Injection,DI)与控制反转(IoC)的含义相同,只不过是从两个角度描述的同一个概念.对于一个Spring初学者来说,这两种称呼都很难理解,我们通过简单的语言来描述这两个概念. 使用对比: 1. 使用前: 当某个Java对象(调用者)需要调用另一个Java对象(被调用者,就是被依赖对象)时,在传统模式下,调用者通常会采用"new被调用者

  • Java详细讲解依赖注入的方式

    目录 Spring中的三种依赖注入方式 可能遇到的问题 Spring中的三种依赖注入方式 Field Injection :@Autowired注解的一大使用场景就是Field Injection Constructor Injection :构造器注入,是我们日常最为推荐的一种使用方式Setter Injection: Setter Injection也会用到@Autowired注解,但使用方式与Field Injection有所不同,Field Injection是用在成员变量上,而Sett

  • Java依赖注入容器超详细全面讲解

    目录 一.依赖注入Dependency Injection 二.解析 2.1 典型的配置文件 2.2 配置文件所对应的Java类 2.3 定义解析器 三.bean工厂(根据bean定义创建bean对象) 四.DI容器(上下文) 4.1 容器接口 4.2 XML容器 五.使用DI容器 一.依赖注入Dependency Injection DI容器底层最基本的设计思路就是基于工厂模式. DI容器的核心功能:配置解析.对象创建.对象声明周期. 完整的代码:Dependency Injection. 二

  • ABP框架的基础配置及依赖注入讲解

    配置ABP 配置是通过在自己模块的PreInitialize方法中来实现的 代码示例如下: public class SimpleTaskSystemModule : AbpModule { public override void PreInitialize() { //在你的应用中添加语言包,这个是英语和作者的土耳其语. Configuration.Localization.Languages.Add(new LanguageInfo("en", "English&quo

  • ASP.NET Core MVC创建控制器与依赖注入讲解

    默认的IControllerActivator 在 ASP.NET Core 中,当 MVC 中间件接收到请求时,通过路由选择要执行的控制器和操作方法.为了实际的执行操作, MVC 中间件必须创建所选控制器的实例. 创建控制器的过程依赖众多不同的提供者和工厂类,但最终是由实现IControllerActivator接口的实例来决定的.实现类只需要实现两个方法: public interface IControllerActivator { object Create(ControllerCont

  • ASP.NET Core依赖注入(DI)讲解

    ASP.NET Core的底层设计支持和使用依赖注入.ASP.NET Core 应用程序可以利用内置的框架服务将服务注入到启动类的方法中,并且应用程序服务也可以配置注入.由ASP.NET Core 提供的默认服务容器提供了最小功能集,并不是取代其他容器. 1.浅谈依赖注入 依赖注入(Dependency injection,DI)是一种实现对象和依赖者之间松耦合的技术,将类用来执行其操作的这些对象以注入的方式提供给该类,而不是直接实例化依赖项或者使用静态引用.一般情况,类会通过构造函数声明器2依

随机推荐