Android Jetpack 浅析Hilt依赖注入

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

什么是依赖注入?

首先,某个类的成员变量称为依赖,如若此变量想要实例化引用其类的方法,可以通过构造函数传参或者通过某个方法获取对象,此等通过外部方法获取对象实例的称为依赖注入;而依赖注入又可以简单分为手动注入自动注入两种方式;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,就首先入手啦;在性能上,我看了一些其他文章上介绍,大差不差的,所有根据自己需要进行选择。

相关文章
|
4月前
|
安全 Java Android开发
安卓开发中的新趋势:Kotlin与Jetpack的完美结合
【6月更文挑战第20天】在不断进化的移动应用开发领域,Android平台以其开放性和灵活性赢得了全球开发者的青睐。然而,随着技术的迭代,传统Java语言在Android开发中逐渐显露出局限性。Kotlin,一种现代的静态类型编程语言,以其简洁、安全和高效的特性成为了Android开发中的新宠。同时,Jetpack作为一套支持库、工具和指南,旨在帮助开发者更快地打造优秀的Android应用。本文将探讨Kotlin与Jetpack如何共同推动Android开发进入一个新的时代,以及这对开发者意味着什么。
|
21天前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
26 6
|
1月前
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
60 8
|
1月前
|
API Android开发 iOS开发
掌握安卓与iOS应用开发中的依赖注入技术
本文探讨了在安卓和iOS应用开发中,如何有效利用依赖注入技术来提升代码的模块化、可测试性和可维护性。通过对比分析两种平台下依赖注入的实现方式与工具,本文旨在为开发者提供一套清晰、实用的依赖管理策略,助力打造高质量软件产品。
|
1月前
|
安全 Java Android开发
探索安卓应用开发的新趋势:Kotlin和Jetpack Compose
在安卓应用开发领域,随着技术的不断进步,新的编程语言和框架层出不穷。Kotlin作为一种现代的编程语言,因其简洁性和高效性正逐渐取代Java成为安卓开发的首选语言。同时,Jetpack Compose作为一个新的UI工具包,提供了一种声明式的UI设计方法,使得界面编写更加直观和灵活。本文将深入探讨Kotlin和Jetpack Compose的特点、优势以及如何结合使用它们来构建现代化的安卓应用。
43 4
|
3月前
|
存储 数据库 Android开发
🔥Android Jetpack全解析!拥抱Google官方库,让你的开发之旅更加顺畅无阻!🚀
【7月更文挑战第28天】在Android开发中追求高效稳定的路径?Android Jetpack作为Google官方库集合,是你的理想选择。它包含多个独立又协同工作的库,覆盖UI到安全性等多个领域,旨在减少样板代码,提高开发效率与应用质量。Jetpack核心组件如LiveData、ViewModel、Room等简化了数据绑定、状态保存及数据库操作。引入Jetpack只需在`build.gradle`中添加依赖。例如,使用Room进行数据库操作变得异常简单,从定义实体到实现CRUD操作,一切尽在掌握之中。拥抱Jetpack,提升开发效率,构建高质量应用!
62 4
|
3月前
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
4月前
|
Android开发
Jetpack Compose: Hello Android
Jetpack Compose: Hello Android
|
13天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
13天前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
51 1