写点什么

在 -Kotlin- 中使用 -Dagger- 会遇到的陷阱和优化方法,android 开发实例大全 PDF

用户头像
Android架构
关注
发布于: 2 小时前

@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<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 方法等,可以缩短项目的构建时间。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
在-Kotlin-中使用-Dagger-会遇到的陷阱和优化方法,android开发实例大全PDF