在网上关于它的资料并不是很多,这也证明它现在并不是很完善,之所以要写一系列关于Kodein
的文章是为保证自己要一直学习新鲜事物。
这篇文章主要介绍Kodein在Android中如何使用
首先我们在app->build.gradle
引入
implementation 'org.kodein.di:kodein-di-generic-jvm:6.5.0'
implementation 'org.kodein.di:kodein-di-framework-android-x:6.5.0'
在自定义的Application中实现KodeinAware
接口,
class MyApp : Application(), KodeinAware {
companion object {
var instance: Application? = null
}
override val kodein = Kodein.lazy {
// bind<Context>() with singleton { this@MyApp }
import(androidXModule(this@MyApp))
// 导入自己写的需要全局使用的Module
// import(module = moduleActivityManager)
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
随便定义一个类
class ActivityManager{
fun getName(): String = "ActivityManagerClass"
}
定义一个TAG,方便debug调试时使用,命名方式module_tag_className
const val MODULE_TAG_ACTIVITY_MANAGER = "module_tag_activity_manager"
val moduleActivityManager = Kodein.Module(MODULE_TAG_ACTIVITY_MANAGER) {
bind<ActivityManager>() with singleton {
ActivityManager()
}
}
通过上面code我们明确了以下三件事情
可以看到这比Dagger
要简单许多,不用在声明component,module,provider
等注解,这更加Kotlin
,接下来就是在MainActivity
中去使用我们创建ActivityManager
实例
class MainActivity : AppCompatActivity(), KodeinAware {
// closesKodein 函数返回了相邻上层的一个Kodien容器,
// 对于Activity来说它返回的是Application层级的kodein容器
private val parentKodein by closestKodein()
override val kodein: Kodein by retainedKodein {
// 通过extend()函数,我们将Application层级的Kodien容器也放在了Activity的kodien容器中,
// 这样activity就能从上层的Kodein容器取出对应依赖
extend(parentKodein, copy = Copy.All)
// 定义一个moduleActivityManager以存放MainActivity所需依赖的绑定函数
import(moduleActivityManager)
bind<Activity>() with instance(this@MainActivity)
}
private val am: ActivityManager by instance()
private val am2: ActivityManager by instance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 这里我们为了证明`singleton`关键字是正确的,我们定义了两个对象进行比较
println("----------hexl: $am / $am2")
}
}
上面我们用了singleton
这个关键字,但实际开发中我们的对象并不是每一个都需要通过单例去创建这一点毋庸置疑,我们下面一起来看看还有哪些其他的关键字
很简单我们在定义一个UserEntity
类
class UserEntity {
fun print() {
println("----------hexl: hello kodein")
}
}
对UserEntity
这个类提供module
const val MODULE_TAG_USER = "module_tag_user"
val moduleUserEntity = Kodein.Module(MODULE_TAG_USER) {
bind<UserEntity>() with provider {
UserEntity()
}
}
这与上面我们创建ActivityManager
很相像,但唯一的区别就是我们使用了provider
这个关键字而不是singleton
这对于我们来说非常重要,接下来我们看看如何在MainActivity
中去使用它
class MainActivity : AppCompatActivity(), KodeinAware {
// closesKodein 函数返回了相邻上层的一个Kodien容器,
// 对于Activity来说它返回的是Application层级的kodein容器
private val parentKodein by closestKodein()
override val kodein: Kodein by retainedKodein {
// 通过extend()函数,我们将Application层级的Kodien容器也放在了Activity的kodien容器中,
// 这样activity就能从上层的Kodein容器取出对应依赖
extend(parentKodein, copy = Copy.All)
// 定义一个moduleActivityManager以存放MainActivity所需依赖的绑定函数
import(moduleActivityManager)
//------------------ 新增代码 ------------------//
import(moduleUserEntity)
bind<Activity>() with instance(this@MainActivity)
}
private val am: ActivityManager by instance()
private val am2: ActivityManager by instance()
//------------------ 新增代码 ------------------//
private val userEntity: UserEntity by instance()
private val userEntity2: UserEntity by instance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 这里我们为了证明`singleton`关键字是单例模式的,我们定义了两个对象进行比较
println("----------hexl: $am / $am2")
// 这里我们为了证明`provider`关键字只提供了对象的创建而不保证对象的全局唯一的,我们定义了两个对象进行比较
println("----------hexl: $userEntity / $userEntity2")
}
}