依赖注入框架--koin

  • koin 一个看似官方的注入依赖框架.

  • 资料来源:

    https://insert-koin.io/
    https://www.jianshu.com/p/bccb93a78cee

  • 更新

    1
    20.03.11 初始化

导语

  • 依赖注入…可以把类想象成一个实体,依赖注入是个注射器,可向类中注射增加属性和对象.

  • 这个过程类本身是无感的,所以可以把一些类之间的依赖关系改成依赖注射(入),降低类之间的耦合.

  • Android 中依赖注入首推自然是 G 家的 Dagger2 了.但是学习曲线那是相当陡峭(说起来也奇怪两年前对android 的学习也止步于 Dagger).

  • Dagger2 为了 java 设计,实现对 jetpack 的 ViewModel 支持很费劲,当然 google 在努力解决这一点.

  • 所以呢 Google 继续努力,我转 koin 了.

koin

  • 第一眼感觉是 Kotlin 官方库..

  • 官方的介绍是: 无代理,无代码生成,无反射,纯 kotlin 编写的轻量级注入框架.

  • 严重警告: 源码中大量使用了 DSL 语法和内联函数,如果不熟悉上述两种写法,谨慎翻源码.原理介绍的文章: 当Koin撞上ViewModel

  • 今天只结合 NoWakeLock 说使用了.(我也不太习惯 DSL 的写法😂)

目的

  • NoWakeLock 使用官方的 MVVM 框架,用到依赖注入的主要有
    • Room 数据库需要全局单例,要在 DataRepository 中注入.
    • DataRepository 按照官方架构需要将所有数据更新/获取操作封装,用到的地方一是 Activity 获取应用数据.二是后台 Server 更新数据库.暂定还是保持单例,注入 ViewModel 和 Server.
    • ViewModel 注入 Activity.

使用

  • 更加具体的请参考官方文档

  • 或者 Koin–适用于Kotlin的超好用依赖注入框架,Dagger替代者,Koin史上最详细解说,一篇就够了,妈妈再也不用担心我不会依赖注入了 (这篇就是那抄的)

  • 添加依赖

    1
    2
    3
    4
    5
    6
    7
    8
    // Koin for Android
    implementation "org.koin:koin-android:$koin_version"

    // Koin Android Scope feature
    implementation "org.koin:koin-android-scope:$koin_version"

    // Koin Android ViewModel feature
    implementation "org.koin:koin-android-viewmodel:$koin_version"
  • 如果是 AndroidX

    1
    2
    3
    4
    5
    6
    7
    8
    // Koin AndroidX Scope feature
    implementation "org.koin:koin-androidx-scope:$koin_version"

    // Koin AndroidX ViewModel feature
    implementation "org.koin:koin-androidx-viewmodel:$koin_version"

    // Koin AndroidX Fragment Factory (unstable version)
    implementation "org.koin:koin-androidx-fragment:$koin_version"
  • 初始化.koin 需要在 Application 中初始化要注入的对象.

    • 在 Application.onCreate() 中声明一个 startKoin{} .
    • startKoin{} 中就是要注入的对象.
  • 拐个弯,向了解一下在类中使用注入的方式,假设注射器里面是 Person() 类.

    • val person: Person by inject()
    • val person2 by inject<Person>()
    • val person3 = get<Person>()
    • 基本上就如同声明新对象.
  • 声明注入对象,有3种方式.

    • Factory: 如同声明一个普通对象.
    • Single: 单例模式.无论在类中声明几次都指向同一个对象.
    • viewModel: 这个特殊一点,声明的是我们继承 lifecycle 的 ViewModel.(还没写到 ViewModel)
  • 对于带参数的类声明,可以通过 get() 获取到已经声明的类.如同 DataRepository 需要持有 AppDatabase 一样.

  • startKoin{} 中声明 androidContext(this@xx) ,后面可以直接引用方便获取 Context.

  • 例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var noWakeLockModule = module {
    single { AppDatabase.getInstance(androidApplication()) }
    single { DataRepository(get()) }
    }
    class BasicApp : Application() {
    override fun onCreate() {
    super.onCreate()
    startKoin{
    androidContext(this@BasicApp)
    listOf(noWakeLockModule)
    }
    }
    }

尾巴

  • 其他内容?还没用到,暂时不列举.
  • 尝试换一种写作风格,每次都把文档列举完