其他
在 Kotlin 中使用 Dagger 会遇到的陷阱和优化方法
Dagger https://dagger.dev/
新的教程 https://dagger.dev/tutorial/
Dagger issue https://github.com/google/dagger/issues/900
提高构建效率
v2.18
https://github.com/google/dagger/releases/tag/dagger-2.18
v2.24
https://github.com/google/dagger/releases/tag/dagger-2.24
v2.23 https://github.com/google/dagger/releases/tag/dagger-2.23
allprojects {
afterEvaluate {
extensions.findByName('kapt')?.arguments {
arg("dagger.formatGeneratedSource", "disabled")
arg("dagger.gradle.incremental", "enabled")
}
}
}
kapt {
arguments {
arg("dagger.formatGeneratedSource", "disabled")
arg("dagger.gradle.incremental", "enabled")
}
}
使用 Qualifier 作为 field 的属性
官方文档 https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets
@Inject @field:MinimumBalance lateinit var minimumBalance: BigDecimal
@Inject @MinimumBalance lateinit var minimumBalance: BigDecimal
// @MinimumBalance 被忽略了
@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()
}
}
@Module
abstract class NetworkModule {
@Binds abstract fun provideService(retrofitService: RetrofitService): Service
@Module
companion object {
@JvmStatic
@Provides
fun provideOkHttpClient(): OkHttpClient {
return return OkHttpClient.Builder().build()
}
}
}
@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()
}
}
泛型注入
泛型 https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#variant-generics
@JvmSuppressWildcards https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-suppress-wildcards/index.html
Dagger 的多重绑定特性 https://dagger.dev/multibindings.html
class MyVMFactory @Inject constructor(
private val vmMap: Map<String, @JvmSuppressWildcards
Provider<ViewModel>>
) {
...
}
内联方法体
如果要在 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()
推荐阅读