在-Kotlin-中使用-Dagger-会遇到的陷阱和优化方法

在 Dagger v2.25 版本中已经修复该问题了,如果您使用的是该版本,之前这样的写法会出现问题,现在不会了。

@Inject @MinimumBalance lateinit var minimumBalance: BigDecimal
// 已修复:@MinimumBalance 不再被忽略
复制代码

使用静态的 @Provides 方法来提高性能

如果使用的是静态的 @Provides 方法,那么 Dagger 生成的代码将具有更好的性能。要达成这一效果,使用 Kotlin 中的 object 而不是 class,并在方法前添加 @JvmStatic 注解。这是您应该尽可能遵循的 最佳实践

@Module
object NetworkModule {

@JvmStatic
@Provides
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder().build()
}
}
复制代码

如果需要使用抽象方法,则需要将 @JvmStatic 添加到 companion object 中,并增加 @Module 注解。

@Module
abstract class NetworkModule {

@Binds abstract fun provideService(retrofitService: RetrofitService): Service

@Module
companion object {

@JvmStatic
@Provides
fun provideOkHttpClient(): OkHttpClient {
return return OkHttpClient.Builder().build()
}
}
}
复制代码

或者,您可以将 object 模块代码抽取出来,并将其包含在抽象模块中:

@Module(includes = [OkHttpClientModule::java])
abstract class NetworkModule {

@Binds abstract fun provideService(retrofitService: RetrofitService): Service

}

@Module
object OkHttpClientModule {

@JvmStatic
@Provides
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder().build()
}
}
复制代码

在 Dagger v2.25 版本中,您不再需要使用 @JvmStatic 来标记 @Provides 函数了,Dagger 会正确地识别它。

泛型注入

Kotlin 使用通配符编译泛型使 Kotlin API 和 Java 能一起使用。当某个参数或者字段的类型为 泛型 时,会在 Java 代码中自动生成。比如,Kotlin 的代码 List 参数就会在 Java 中显示为 List<? super Foo>。

但这种特性会导致在 Dagger 中出现问题,因为它期望类型是完全 (也称 invariant) 匹配的。使用 @JvmSuppressWildcards 将确保 Dagger 会看到没有通配符的类型。

当您使用 Dagger 的多重绑定特性时,这是一个常常会遇到的问题,比如:

class MyVMFactory @Inject constructor(
private val vmMap: Map<String, @JvmSuppressWildcards
Provider>

) {

}
复制代码

在 Dagger v2.25 版本中,您将不再需要使用 @JvmSuppressWildcards 了,Dagger 会正确地识别它。

内联方法体

Dagger 通过检查返回值类型来确定由 @Provides 方法配置的类型。在 Kotlin 函数中的返回类型是可选的,甚至 IDE 有时也会建议您重构代码使用内联方法体来隐藏返回值类型的声明。

如果推断的类型与您所期望的类型不一致,就会引起 bug 出现。我们来看一些例子:

如果要在 Dagger 中添加特定的类型,使用内联将是最好的选择。我们来看看在 Kotlin 中实现同样效果的另外一种方法:

@Provides
fun provideNetworkPrinter() = NetworkPrinter()

@Provides
fun provideNetworkPrinter(): NetworkPrinter = NetworkPrinter()

@Provides
fun provideNetworkPrinter(): NetworkPrinter {
return NetworkPrinter()
}
复制代码

如果您需要提供接口的实现,则必须显示指定返回类型。不这样做的话会出问题:

@Provides
// 配置 Printer
fun providePrinter(): Printer = NetworkPrinter()

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

阿里P7Android高级教程

下面资料部分截图,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。

Android核心高级技术PDF资料,BAT大厂面试真题解析;

-1712078760707)]

附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。

Android核心高级技术PDF资料,BAT大厂面试真题解析;
[外链图片转存中…(img-Ap6qjRob-1712078760708)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值