文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

这篇文章主要讲解了“在Kotlin中使用Dagger会遇到的陷阱和优化方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“在Kotlin中使用Dagger会遇到的陷阱和优化方法是什么”吧!

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

提高构建效率

为了缩短构建时间,Dagger 在 v2.18 版本中新增了 对 gradle 增量注解处理 (gradle’s incremental  annotation processing) 的支持。在 Dagger v2.24  版本中这个功能是默认启用的。如果您使用的是较低版本,您需要添加以下几行代码来激活该功能。

另外,您可以配置 Dagger 让它不要格式化生成的代码。这一选项是在 Dagger v2.18 版本中添加的,并且是 v2.23 版本中的默认行为  (不再生成格式化代码)。如果您使用的是较低的版本,同样可以添加下面的代码来禁用格式化代码以缩短构建时间。

在 build.gradle 中添加以下编译参数来提高 Dagger 在构建时的性能:

allprojects {     afterEvaluate {         extensions.findByName('kapt')?.arguments {             arg("dagger.formatGeneratedSource", "disabled")             arg("dagger.gradle.incremental", "enabled")         }      } }

另外,如果您使用的是 Kotlin DSL 脚本文件,那么您需要在 build.gradle.kts 文件中包含以下内容:

kapt {     arguments {         arg("dagger.formatGeneratedSource", "disabled")         arg("dagger.gradle.incremental", "enabled")     } }

使用 Qualifier 作为 field 的属性

在 Kotlin 的某个 property 上添加注解时,不清楚最终 Java 是否能够在该 property 的 field 或者 method  中获取到该注解。在注解之前添加 field: 前缀能够确保 qualifier 会作用到正确的地方 (查看 官方文档 获取更多详情)。

将 qualifier 作用于一个已注入的 field 的正确方法如下:

@Inject @field:MinimumBalance lateinit var minimumBalance: BigDecimal

下面的做法是不对的:

@Inject @MinimumBalance lateinit var minimumBalance: BigDecimal  // @MinimumBalance 被忽略了

忘记添加 field: 如果在 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。

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

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

class MyVMFactory @Inject constructor(   private val vmMap: Map<String, @JvmSuppressWildcards  Provider<ViewModel>>  ) {      ...  }

在 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()  @Provides // 配置 NetworkPrinter,不是一个普通的 Printer fun providePrinter() = NetworkPrinter()

Dagger 基本上是同 Kotlin 兼容的,但是您仍然要注意,来确保代码不会出问题: 使用 @field:  来限定字段属性,内联方法体,当对集合进行注入时使用 @JvmSuppressWildcards 注解。

本次 Dagger 带来的优化不会带来额外的损耗,遵循这些最佳实践,诸如启用增量注释处理、禁用格式化设置以及使用静态 @Provides  方法等,可以缩短项目的构建时间。

感谢各位的阅读,以上就是“在Kotlin中使用Dagger会遇到的陷阱和优化方法是什么”的内容了,经过本文的学习后,相信大家对在Kotlin中使用Dagger会遇到的陷阱和优化方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯