Author: aa86799@163.com
date: 2020-09-09 00:10

文章目录

  • 文档地址
  • 依赖配置
  • @HiltAndroidApp
  • 将依赖项注入 Android 类
    • @Inject 注入
  • 定义 Hilt 绑定
    • 使用 @Binds 注入接口实例
    • 使用 @Provides 注入实例
    • 为同一类型提供多个绑定,使用限定符 @Qualifier
    • 预定义限定符:@ApplicationContext, @ActivityContext
  • Hilt 组件
    • 组件生命周期
    • 组件作用域
  • 组件层次结构
  • 在 Hilt 不默认支持的类中注入依赖项
    • 实例:普通类注入 不同的Retrofit(不同的baseUrl) 对象
    • 实例:普通类 注入 Repository
  • 使用 Hilt 注入 ViewModel 对象
  • 使用 Hilt 注入 WorkManager

文档地址

https://developer.android.google.cn/training/dependency-injection/hilt-android

点击进入Hilt官网,了解更多细节

依赖配置

project/build.gradle

# 2021-05 hilt已发布正式版,最新版本,直接上hilt官网查看
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.28-alpha'

app/build.gradle

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

@HiltAndroidApp

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

@HiltAndroidApp 会触发 Hilt 的代码生成操作, 生成的代码包括应用的一个基类,该基类充当应用级依赖项容器

将依赖项注入 Android 类

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() { ... }

Hilt 目前支持以下 Android 类:

  • Application(通过使用 @HiltAndroidApp
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver (直接用@AndroidEntryPoint注入不成功)
  • ContentProvider (直接用@AndroidEntryPoint注入不成功)

注意:在 Hilt 对 Android 类的支持方面还要注意以下几点:

  • Hilt 仅支持扩展 ComponentActivity 的 Activity,如 AppCompatActivity
  • Hilt 仅支持扩展 androidx.Fragment 的 Fragment。
  • Hilt 不支持保留的 Fragment。

@Inject 注入

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {@Inject lateinit var analytics: AnalyticsAdapter...
}

定义 Hilt 绑定

向 Hilt 提供绑定信息的一种方法是构造函数注入。在某个类的构造函数中使用 @Inject 注释,以告知 Hilt 如何提供该类的实例:

class AnalyticsAdapter @Inject constructor(@Inject lateinit var service: AnalyticsService
) { ... }

在本例中,AnalyticsServiceAnalyticsAdapter 的一个依赖项。因此,Hilt 还必须知道如何提供 AnalyticsService 的实例。

使用 @Binds 注入接口实例

interface AnalyticsService {fun analyticsMethods()
}// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
class AnalyticsServiceImpl @Inject constructor(...
) : AnalyticsService { ... }@Module
@InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {@Bindsabstract fun bindAnalyticsService(analyticsServiceImpl: AnalyticsServiceImpl): AnalyticsService
}

Hilt 模块 AnalyticsModule 带有 @InstallIn(ActivityComponent::class) 注释,因为您希望 Hilt 将该依赖项注入 ExampleActivity。此注释意味着,AnalyticsModule 中的所有依赖项都可以在应用的所有 Activity 中使用。

使用 @Provides 注入实例

如果某个类不归您所有(因为它来自外部库,如 Retrofit、OkHttpClient 或 Room 数据库等类),或者必须使用构建器模式创建实例,也无法通过构造函数注入。

@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {@Providesfun provideAnalyticsService(// Potential dependencies of this type): AnalyticsService {return Retrofit.Builder().baseUrl("https://example.com").build().create(AnalyticsService::class.java)}
}

为同一类型提供多个绑定,使用限定符 @Qualifier

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherInterceptorOkHttpClient

方式一

@AuthInterceptorOkHttpClient
@Provides
fun m():OkHttpClient

方式二

@Provides
fun m(@AuthInterceptorOkHttpClient client: OkHttpClient):...

方式三

class ExampleServiceImpl @Inject constructor(@AuthInterceptorOkHttpClient private val okHttpClient: OkHttpClient
)

方式四

@AuthInterceptorOkHttpClient
@Inject lateinit var okHttpClient: OkHttpClient

与binds结合:(官方文档没写,猜想应该是可以的)

@Binds
@AuthInterceptorOkHttpClient
abstract fun bind(): OkHttpClient

预定义限定符:@ApplicationContext, @ActivityContext

class AnalyticsAdapter @Inject constructor(@ActivityContext private val context: Context,private val service: AnalyticsService
) { ... }

Hilt 组件

@InstallIn 注释中引用相应的组件。限定了注入的实例的生命周期范围。

Hilt 组件 注入器面向的对象
ApplicationComponent Application
ActivityRetainedComponent ViewModel
ActivityComponent Activity
FragmentComponent Fragment
ViewComponent View
ViewWithFragmentComponent 带有 @WithFragmentBindings 注释的 View
ServiceComponent Service

组件生命周期

生成的组件 创建时机 销毁时机
ApplicationComponent Application#onCreate() Application#onDestroy()
ActivityRetainedComponent Activity#onCreate() Activity#onDestroy()
ActivityComponent Activity#onCreate() Activity#onDestroy()
FragmentComponent Fragment#onAttach() Fragment#onDestroy()
ViewComponent View#super() 视图销毁时
ViewWithFragmentComponent View#super() 视图销毁时
ServiceComponent Service#onCreate() Service#onDestroy()

注意ActivityRetainedComponent 在配置更改后仍然存在,因此它在第一次调用 Activity#onCreate() 时创建,在最后一次调用 Activity#onDestroy() 时销毁。

组件作用域

Android 类 生成的组件 作用域
Application ApplicationComponent @Singleton
View Model ActivityRetainedComponent @ActivityRetainedScope
Activity ActivityComponent @ActivityScoped
Fragment FragmentComponent @FragmentScoped
View ViewComponent @ViewScoped
带有 @WithFragmentBindings 注释的 View ViewWithFragmentComponent @ViewScoped
Service ServiceComponent @ServiceScoped

默认情况下,Hilt 中的所有绑定都未限定作用域。这意味着,每当应用请求绑定时,Hilt 都会创建所需类型的一个新实例。

若限定作用域,如:

@ActivityScoped
class AnalyticsAdapter @Inject constructor(private val service: AnalyticsService
) { ... }

@ActivityScoped: Hilt 会在相应 Activity 的整个生命周期内提供 AnalyticsAdapter 的同一实例.

组件层次结构

父组件中绑定的依赖项,对子组件是可见的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xCeJBtzE-1604903187718)(https://developer.android.google.cn/images/training/dependency-injection/hilt-hierarchy.svg)]

注意:默认情况下,如果您在视图中执行字段注入,ViewComponent 可以使用 ActivityComponent 中定义的绑定。如果您还需要使用 FragmentComponent 中定义的绑定并且视图是 Fragment 的一部分,应将 @WithFragmentBindings 注释和 @AndroidEntryPoint 一起使用。

在 Hilt 不默认支持的类中注入依赖项

@EntryPoint 创建入口点。

ContentProvider 不能直接使用 @AndroidEntryPoint ; BroadcastReceiver 也不能。

class ExampleContentProvider : ContentProvider() {@EntryPoint@InstallIn(ApplicationComponent::class)interface ExampleContentProviderEntryPoint {fun analyticsService(): AnalyticsService}...
}

实例:普通类注入 不同的Retrofit(不同的baseUrl) 对象

@EntryPoint
@InstallIn(ApplicationComponent::class)
interface FleetRetrofitProviderEntryPoint {@FleetRetrofitfun getFleetRetrofit(): Retrofit//再定义一个不同的 Retrofit baseUrl 的 对象获取函数,不同的 Qualifier
}{//val appContext = ExpressApplication.instance().applicationContext?: throw IllegalStateException()val networkModule = EntryPointAccessors.fromApplication(appContext, FleetRetrofitProviderEntryPoint::class.java)val retrofit = networkModule.getFleetRetrofit() //获取相应的Retrofitval result = retrofit.create(LoginService::class.java).m()...
}

详情见 fleet项目中的 NetworkModule, LoginBiz

实例:普通类 注入 Repository

@EntryPoint
@InstallIn(ApplicationComponent::class)
interface LocationReceiverEntryPoint {fun repository(): LocationUploadRepository
}{val entry = EntryPointAccessors.fromApplication(ExpressApplication.instance().applicationContext, LocationReceiverEntryPoint::class.java)val result = entry.repository().updateLocation(LocationUploadBody(locationItems))
}

详情见 fleet项目中的 LocationUpdatesBroadcastReceiver

使用 Hilt 注入 ViewModel 对象

app/build.gradle

dependencies {...implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'// When using Kotlin.kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'// When using Java.annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
}

ViewModel 对象的构造函数中使用 @ViewModelInject 注释来提供一个 ViewModel。您还必须使用 @AssistedSavedStateHandle 依赖项添加注释:

class ExampleViewModel @ViewModelInject constructor(private val repository: ExampleRepository,@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {...
}

然后,带有 @AndroidEntryPoint 注释的 Activity 或 Fragment 可以使用 ViewModelProviderby viewModels() KTX 扩展 照常获取 ViewModel 实例:

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {private val exampleViewModel: ExampleViewModel by viewModels() //or activityViewModels()...
}

androidx.lifecycle.SavedStateHandle 用于 Activity/Fragment重建时保存变量用的。

  • getLiveData(key, [v]): MutableLiveData 获取不到,会内部创建 LiveData; 一个key对应一个LiveData,存放在一个 Map<String, LiveData>中。
  • keys(): Set
  • set(key, v) 从map中,若取得 LiveData,则liveData.setValue(); 若取不得则存放在 一个Map<String, Object> 中。
  • get(key) 从Map<String, Object> 中 get(key)。

使用 Hilt 注入 WorkManager

app/build.gradle

dependencies {...implementation 'androidx.hilt:hilt-work:1.0.0-alpha01'// When using Kotlin.kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'// When using Java.annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
}

Worker 对象的构造函数中使用 @WorkerInject 注释来注入一个 Worker。您只能在 Worker 对象中使用 @Singleton 或未限定作用域的绑定。您还必须使用 @AssistedContextWorkerParameters 依赖项添加注释:

class ExampleWorker @WorkerInject constructor(@Assisted appContext: Context,@Assisted workerParams: WorkerParameters,workerDependency: WorkerDependency
) : Worker(appContext, workerParams) { ... }

然后,让 Application 类实现 Configuration.Provider 接口,注入 HiltWorkFactory 的实例,并将其传入 WorkManager 配置:

@HiltAndroidApp
class ExampleApplication : Application(), Configuration.Provider {@Inject lateinit var workerFactory: HiltWorkerFactoryoverride fun getWorkManagerConfiguration() =Configuration.Builder().setWorkerFactory(workerFactory).build()
}

Android Dagger-Hilt 依赖注入相关推荐

  1. android组件浮动在activity上_Jetpack Hilt 依赖注入框架上手指南

    code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群 作者:LvKang-insist 链接:https://juejin.im/post/5efdff9d6fb9a07e ...

  2. Android hilt 依赖注入使用详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/128424833 本文出自[赵彦军的博客] 文章目录 官方文档 作用域于树图 添加依 ...

  3. [Android]使用Dagger 2依赖注入 - DI介绍(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...

  4. [Android]使用Dagger 2依赖注入 - 自定义Scope(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5095426.html 使用Dagger 2依赖注入 - 自定义 ...

  5. 具有Hilt的Android上的依赖注入

    重点 (Top highlight) Dependency injection (DI) is a technique widely used in programming and well suit ...

  6. Android开源框架——依赖注入Dagger

    介绍:Dagger是Square公司开发依赖注入框架,主要针对辅助类对象,而ButterKnife是针对View视图对象的. github:https://github.com/square/dagg ...

  7. Android开发中依赖注入的应用

    什么是依赖注入? 依赖是指一个对象持有其他对象的引用.依赖注入则是将这些依赖对象传递给被依赖对象,而不是被依赖对象自己创建这些对象.  public class MyClass{private Ano ...

  8. Android开源框架——依赖注入ButterKnife

    若对依赖注入不熟悉,请阅读博客中的另外一篇IOC控制反转浅析 介绍:ButterKnife是Square公司员工JakeWharton开发的一款针对View视图对象的依赖注入库.目的是通过依赖注入方式 ...

  9. Android 依赖注入可以更简单 —— 新版本 Dagger 2 使用教学

    今年 3 月 21 号 Dagger 2 在 2.10 版本之后针对 Android 方面做了很大的优化,使用方法也随之有了不少变化.本次改动除了让 Dagger 2 的使用更加符合控制反转原则,还针 ...

  10. [Android]使用Dagger 2进行依赖注入 - Producers(翻译)

    使用Dagger 2进行依赖注入 - Producers 原文:http://frogermcs.github.io/dependency-injection-with-dagger-2-produc ...

最新文章

  1. NanoPi NEO Air使用十一:编写SPI驱动点亮TFT屏幕,ST7789V
  2. Python词云 wordcloud 十五分钟入门与进阶
  3. 新安装和已安装nginx如何添加未编译安装模块/补丁
  4. 【struts2】struts2配置文件—struts.properties
  5. c语言大作业旋转,c语言大作业全-20210412035629.docx-原创力文档
  6. C语言之常见错误解决办法
  7. lodop转到其他html页面,Lodop实现打印功能
  8. mv强制覆盖 shell_生产力工具:shell 与 Bash 脚本
  9. python 列表有没有顺序_python-如何获取列表的所有顺序,以使该列表等于另一个列表?...
  10. Jenkins 新版本及插件在Windows下的安装
  11. 在KVM虚拟机中使用spice系列之二(USB映射,SSL,密码,多客户端支持)
  12. 收集的一些discuz插件常用插件分享给大家了
  13. windows xp sp3(XP3)无法安装或使用iis的根本原因及解决办法研究
  14. 341编程器 软硬件
  15. 【神经网络】综合篇——人工神经网络、卷积神经网络、循环神经网络、生成对抗网络
  16. microsoftstore连不上网_修复Microsoft Store 无法连接网络 代码: 0x80072EFD
  17. 已知三角形的三条边长,求这个三角形的外接圆的半径
  18. 银河土星_设计师来自土星,开发人员来自木星:或者,为什么沟通很重要
  19. 代码防御性编程的十条技巧
  20. 华为手机无法安装ADB和HDB的处理

热门文章

  1. 计算机技能测试题五,计算机技能测试题十五
  2. 一个计算机专业学生几年的编程经验汇总
  3. 与米老师的谈话之我的总结误区
  4. 几个高效的字符串匹配算法
  5. new InitialContext() 创建ejb实例的过程
  6. 广西省钦州市谷歌卫星地图下载
  7. 如何为neo4j中的【关系】添加or修改【属性】?
  8. 滴滴打车And 360 校招 2016 在线笔试(一)
  9. 有哪些国内最好的危机公关公司分享。
  10. 如何高效地在网上找开源项目做!