美文网首页Android开发AndroidAndroid开发
5. 【浅入深出理解 dagger、Hilt】 - Hilt进阶

5. 【浅入深出理解 dagger、Hilt】 - Hilt进阶

作者: zhongjh | 来源:发表于2022-05-10 16:51 被阅读0次

    该章站在企业项目角度上如何在MVVM框架上完善并且合理的使用Hilt。

    所以如果没了解MVVM的结构建议可以直接忽略这章。大家知道,MVVM里面View和Model之间有关联,假设一个场景View触发一个点击事件调用Model查询,然后Model会调用相关Http类进行查询,返回数据给Model,Model再返回数据给View。
    当然上述表达的不是严格意义的MVVM,但是流程相仿,主要是讲解如何注解Model和相关Http类,让他们自动生成

    让我们先看看有哪些类


    image.png
    类名 解释
    MyApplication app的入口
    MainActivity 顾名思义就是展示的View
    ViewModel MainActivity对应的ViewModel,也是MVVM中的Model
    TestApi 一个仿造Http的类,只是单纯返回一个数据
    NetworkModule 一个制造类,Hilt通过标记自动寻找相关类,然后会找到该类调用相关函数实例化TestApi

    那么让我们直接快速讲解

    1. 在Project的build.gradle添加引入
        dependencies {
            ...
            classpath "com.google.dagger:hilt-android-gradle-plugin:2.36"
        }
    
    2. 在module的build.gradle分别两处地方添加
    plugins {
        ...
        id 'kotlin-kapt'
        id 'dagger.hilt.android.plugin'
    }
    
    dependencies {
        ……
    
        implementation "com.google.dagger:hilt-android:2.37"
        kapt "com.google.dagger:hilt-android-compiler:2.37"
    }
    

    好了!添加相关插件自动下载后,我们继续!

    3. HiltAndroidApp标记Application
    @HiltAndroidApp
    class MyApplication : Application()
    

    跟dagger有点不一样的是,必须包含一个带有 @HiltAndroidApp标记的Application类。
    当然,别忘记修改AndroidManifest.xml

    <application
            android:allowBackup="true"
            android:name=".MyApplication"
            ...
    </application>
    
    5. Activity
    @AndroidEntryPoint
    class MainActivity : AppCompatActivity() {
    
        private val viewModel: ViewModel by viewModels()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
            binding.tvName.append(viewModel.shopBanner.toString())
        }
    }
    

    大家看到viewModel就很奇怪,没有标记就能自动生成使用了?其实by viewModels()就已经代表Hilt生成处理了。让我们往下看

    4. 创建一个仿造访问网络数据的TestApi 类
    class TestApi {
        fun getValue(): Int {
            return 1
        }
    }
    

    只是一个简单的创建返回数据类

    5. ViewModel

    可以同时看到两个标记@HiltViewModel@Inject,那么TestApi在哪里实例化呢?Activity也没有创建TestApi呀,这就是Hilt方便的地方,让我们看下一个NetworkModule

    @HiltViewModel
    class ViewModel @Inject constructor(
        testApi: TestApi
    ) : ViewModel() {
    
        val shopBanner = testApi.getValue()
    }
    
    6. NetworkModule

    通过@Module@InstallIn@Provides@Singleton等多个标记,让Hilt寻找TestApi的构造方法的时候,找到这里,并且调用GetApi方法创建实例。

    @Module
    @InstallIn(SingletonComponent::class)
    object NetworkModule {
    
        @Provides
        @Singleton
        fun GetApi(): TestApi {
            return TestApi()
        }
    
    }
    
    7. End

    基本就结束了,那么大家很奇怪,其实很简单两句话代码放在MainActivity直接实例化不就行了吗,其实不是这样的,当项目越庞大的时候,可能改变构造函数的时候,那么我们使用Hilt就能很方便的集中在类似NetworkModule这样的类处理,而在Activity这些类中,我们是不需要关心构造函数的。如果你觉得理解还抽象,那么建议先用平常方式写Mvvm,最后再用Hilt优化这方面,或许会有更深入的理解呢!

    标记符讲解表格

    标记符 标记是为了什么
    @Module 标记一个module,代表提供一些无法用构造@Inject的依赖, 比如接口, 第三方库类型, Builder模式构造的对象等
    @InstallIn 委托Hilt帮我们管理范围,以管理对象的生命周期,通过指定 Hilt 组件告诉 Hilt 绑定在哪些容器中可用,有很多种容器具体可以看图1
    @Provides 提供实例,注释函数,以告诉 Hilt 如何提供无法注入构造函数的 类型
    @ViewModelScoped 当在ViewModel中引入协程,如果直接使用CoroutineScope,那么需要在onCleared()方法中取消协程,如果忘记取消协程那么会导致出现内存泄漏等各种问题,此时需要使用ViewModel扩展属性viewModelScope来实现协程作用域

    作用域

    图1

    只是简单介绍依赖注入使用方式的实例源码如下:
    zhongjhATC/HiltAndDaggerDemo: 演示 Hilt、Dagger 的demo (github.com)

    其他相关文章
    1. 【浅入深出理解 dagger、Hilt】 - 简介 - 简书 (jianshu.com)
    2. 【浅入深出理解 dagger、Hilt】 - dagger无参依赖注入 - 简书 (jianshu.com)
    3. 【浅入深出理解 dagger、Hilt】 - dagger有参依赖注入 - 简书 (jianshu.com)
    4. 【浅入深出理解 dagger、Hilt】 - Hilt - 简书 (jianshu.com)
    在 Android 应用中使用 Hilt | Google Developers

    相关文章

      网友评论

        本文标题:5. 【浅入深出理解 dagger、Hilt】 - Hilt进阶

        本文链接:https://www.haomeiwen.com/subject/ztnhurtx.html