kotlin之koin

Koin是一款适用于Android的轻量级依赖注入框架,无需代理、代码生成和反射。本文介绍了如何进行Gradle配置、定义依赖对象、初始化Koin、注入依赖以及如何处理动态依赖和作用域管理。通过示例展示了在Activity和Fragment中使用Koin的多种方式,包括factory和single模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Koin是一款轻量级的依赖注入框架,根据官方的描述,它无代理,无代码生成,无反射。

第一步:Gradle Setup

// Add Jcenter to your repositories if needed
repositories {
    jcenter()    
}
dependencies {
// Koin for Android
compile "org.koin:koin-android:1.0.1"
// Koin Android Scope feature
compile "org.koin:koin-android-scope:1.0.1"
// Koin Android ViewModel feature
compile "org.koin:koin-android-viewmodel:1.0.1"
}

第二步:使用 Koin 之前,先建立一个依赖对象

import com.jastzeonic.koinsample.model.Dog
import org.koin.dsl.module.module

val creatureModule = module {
    factory {
        Dog()   
    }
}

第三步:初始化
自然的,我们得告诉koin它需要这个module,这就是所谓的初始化,时机就是app诞生时,所以要在application中来做startkoin初始化的动作。

mport org.koin.android.ext.android.startKoin

class CreatureApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        startKoin(this,listOf(creatureModule))

    }

}

第四步:注入
然后我们再来看怎么inject给依赖者,

class CreatureActivity : AppCompatActivity() {

    //Just use val and by inject
    private val creature:Dog by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_creature)
        Glide.with(this).load(creature.image())
                .into(creature_image)
        creature_image.postDelayed({
            Toast.makeText(this.applicationContext, creature.shout(), Toast.LENGTH_LONG).show()
        }, 500)
    }
}

或者可以写成:

class CreatureActivity : AppCompatActivity() {

    private lateinit var creature:Dog

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_creature)
        
        creature = get()
      
        Glide.with(this).load(creature.image())
                .into(creature_image)
        creature_image.postDelayed({
            Toast.makeText(this.applicationContext, creature.shout(), Toast.LENGTH_LONG).show()
        }, 500)


    }
}

考虑一种情况:假如 Activity 的依赖对象 Presenter 也依赖着另一个依赖对象 Repository ,使用 Koin 则会写成这样:

val appModule = module {
    single{ Repository() }

    factory{ Presenter(get())}
}

以上的写法,在编译前就决定好依赖的是哪个类型 了,如果希望在Runtime时决定要inject什么类型呢 ?

val creatureModule = module {
    factory { (creatureType: Int) ->
        when (creatureType) {
            Creature.TYPE_DOG -> Dog()
            Creature.TYPE_CAT -> Cat()
            else -> {
                Dog()
            }
        }
    }
}
class CreatureActivity : AppCompatActivity() {
    companion object {
        const val CREATURE_TYPE = "creature_type"
    }

    private lateinit var creature: Creature

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_creature)
        val creatureType = intent.getIntExtra(CREATURE_TYPE, 0)
      
        // Injection parametersOf(...)
         creature = get { parametersOf(creatureType) }

        Log.v("tag", "CreatureActivity$creature")

        Glide.with(this).load(creature.image())
                .into(creature_image)

        creature_image.postDelayed({
            Toast.makeText(this.applicationContext, creature.shout(), Toast.LENGTH_LONG).show()
        }, 500)
    }
}

还有几件事:

factory
用到的时候就新建一个

Scope
希望能够在某个Activity上让两个以上的Fragment共用,可以这样使用:

val creatureModule = module {
    scope("DogSession") {
        Dog()
    }
}
class ScopeDemoActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_scope_demo)

        bindScope(createScope("DogSession"))
    }
}

这样在Fragment里面就可以正常的inject

class FragmentA : Fragment() {

    private val dog: Dog by inject()
  ...
}

class FragmentB : Fragment() {

    private val dog: Dog by inject()
  ...
}

在两个activity之间公用这个实例,写法如下:

getKoin().createScope("DogSession")

然後在兩個 Activity 裡面 inject:

class MyActivity1 : AppCompatActivity() {
    val dog : Dog by inject()
}
class MyActivity2 : AppCompatActivity() {
    val dog : Dog by inject()
}

single :
直到 App 結束前都會一直存在

val creatureModule = module {
    single {
        Dog()
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值