写在前面
内容学习了郭霖的 Hilt 文章:Jetpack新成员,一篇文章带你玩转Hilt和依托注入
预览
1. Application DSL
KoinApplication
装备 Koin 注入的进口,有一下 API 可运用:
-
koinApplication { }
:创立一个 Koin 容器。 -
startKoin { }
:创立一个 KAPPoin 容器并将之注册到GlobalContext
中,如此能够运用GlobalContext
的 API 。 -
logger( )接口类型
:挑选运用什么 Log 方法,Koin 供给了 3 种默许 Logger ,分别是 AndroidLogger 、PrintapproachLogger 、EmptyLogger ,它们都继接口卡承自抽象类 Logger ,如不装备默许运用 EmptyLogger ,即不打印。 -
modules( )
:装备 Koin 模块并将之注入到 Koin 容器。 -
properties()
:运用 HashMap 注入特色,供全局查询修正。 -
fileProperties( )
:运用给定 properties 文件注入特色,文javascript件需求放在 src/main/resources 目录下。 -
environmentPropeappearrties( )
:注入体系、环境特色,经过java.lang.System
注入。
2. Module DSL
-
module { // module content }
:创立一个 Koin 模块。android是什么手机牌子 -
factory { //definition }
:创立注approach入类的实例。 -
single { //definition }
:与android手机factory
功用一起,只android下载安装不过创立的是单例。 -
get()
:经过解析组件依托,注入类实例。 -
inject()
:与get()
功用一起,都是供给类注入,但injec接口自动化t
是懒加载。 -
b接口文档ind()
:为注入类添加类型绑定,因为默许注入类只能对应一个类型。 -
binds()
:功用与上述bind()
一起,一次性供给多个类型绑定。 -
scope { // scope group }
:为下述scoped
界说一个合理的组,效果是控制注入类的生命周期。 -
scoped { //definition }java面试题
:与上述scope
协作APP运用,界说内放注入类的实例,标明只在sandroid的drawable类cope
的范围内存在。 -
named()
:假定遇到相同类型需求两个或以上的注入,能够经过这个函数给注入进行命名,然后在注入处只需指定好称号即可获取正确的注入。
场景
1. 简略注入
-
首要封装一下常用的 API ,接Android下来都会appreciate用到这些封装 API :
inline fun <reified T :java面试题 Any> get( qualifier: Qjavaeeualifier? = null, noinline paramapp下载eterandroid是什么手机牌子s: ParametersDefinition? = null ): T { return GlobalContext.get().get<T>(qualifier, pa接口测验rameters) } inline fun <reiandroid平板电脑价格fied T : Any> inject( qualifier: Qualifier? = null, mode: LazyThre接口卡adSafetyMode = KoinPlatformTools.接口类型defaultLazandroid体系yMode(), noinline parameters: ParametersDefiniapplicationtion? = null ): Lazy<T> { return GlobalContext.get().inject(qualifieapplicationr, mode, parameters) }android/yunos
这儿首要针对
GlobalContext.g接口测验et()
进行了封接口类型装,否则接口卡在事务代接口码中免不了需求写多一些样板代码。 -
接下来装备一下注入信息,例如需求一辆车需求引擎:
class Car val module = modules { factory { Car(android手机) } } class App : Application() { override fun onCreate() { super.onCreate() startKoin { modules(module) } } }
-
然后就能够在调用处进行注入了:
private val car = get<Car>() // or private val car by inject<Car>()
2. 带参数注入
-
给
Car
注入一个司机:class Driver class Car(val driver: DJavariver) vajava环境变量装备l module = moduleappetite { factory { params -> Car(params.get()) } // or fact接口和抽象类的差异ory { (drivjava语言er: Driver) ->approach; Car(driver) } }
在配approach备时我们运用到了
Definition<T>
,这是factory()
和single()
函数里界说的,它的原型是Scope.(JavaParametersHolderappreciate) -> T
,我们能够经过 ParametersHolder 取出我们需求的参数进行创立目标,假定运用解构声明则参数最多只接受 5 个,超出无法运接口和抽象类的差异用解构声明,看代码:val module = modulandroid下载安装e { factory { (p1: Byte, p2: Short, p3: Inappstoret, p4: Long, p5: String) -> Obj(p1,java怎么读 p2, p3, p4, p5) } // 超出 5 个后手动调用 params 获取 factory { pjavascriptarams -> Obj(params[app是什么意思0], params[1], params[2], params[3], params[4], params[5]) } } private val obj = get<Obj> { parametersOf( 1, 2, 3, 4L, "", //... ) }
注入时运用到了
ParametersDefinition
,这是get()
和injejava模拟器ct()
函数里界说的,它的原型是() -> ParametersHolder
,意味着需求回来一个Parametersjava怎么读Holdeandroid下载r
给 Koin ,经过parametersOf()android平板电脑价格
函数传android下载入参数,支撑可变参数。
3. 接口注入
-
给车注入引擎:
interfa接口自动化ce Engine class GasEngine class ElectricEngineapple val module = module { // 绑定为 GasEngine 类型 factory { GasEngine() } // 绑定为 ElectricEngine 类型 factory { ElectricEngine() } } class Car { private val gasEngine = get<GasEngine>() priandroid什么意思vate val electricEngine = get<接口卡ElectricEngine>() }
这样能够结束接口的注入,但存在问题,默许情况下配补白入时只能绑定一个类型,即上述java初学代码各自绑定了
GasEngine
和ElectricEngine
,因此在注入时只能明晰运用装备时绑定的类型,假定运用get<Engiandroid下载安装ne>()
会报找不到界说失常。那假定想要经过
Engine
类型来获取注入该怎么做呢?// 第一种方法是在装备时明晰类型: factory<Engine&gappetitetandroid体系; { GasEngine() } // or factory { GasEngine asjava难学吗 Engine } // 第二种方法是运用 `bind()` 中缀函数: facappetitetory { Ga接口测验sEngine() } bind Engine::class
bind()
函数需求传入想一起绑定的 KClass 类型,假定有多个类型需求一起绑定能够运用binds()
函数传入一个类型 List 。当装备时运用了多类型绑定后,在界说注入时就能够依据想要的类型来进行注入了,但仍需求留心,一java难学吗个类型最多只能有一个装备,新的注入装备会掩盖旧装备(V2 版别中 override 默许关闭需求手动打开,V3 版别默许打开,可手动关闭),下面用比方来阐明:
val module = module { factory { GasEngine() } bind Engine::class factory { ElectricEngine() } bind Engine::class } private val gasEngine = get<Engine&gjava环境变量装备t;() private val electricEngine = get<ElectricEngine>()
运转后能够发现,无论是
gasappreciateEngine
还是eleappointmentctrictEngine
,都会注入了ElectricEngine
,因为在第二行装备时一起绑定了Engine
类型,导致上一行的装备被掩盖,假定去除第二行装备的bind Engine::class
即康复正常。那假定的确需求注入多个同类型该怎么办呢?下面会说到。
4. 相同类型注入
直接上代码:
val module = module {
factory(named("ga接口测验s")) { GasEngine() } bind Engine::class
factory(named("electric")) { ElectricEngine() } bind Engine::class
}
private var gasEngine = get<Engine>(named("gas"))
private var electricEngine = get<Engine>(named("electric"))
在装备与注入时均运用到了 Qualifier
约束符,factory()
和 single()
函数都有供给形参,经过 named()appreciate
函数获取到 Qualifier
并传入即可获取需求的效果。
named()
支撑 3 种运用方法:
-
named<KClass>()
:经过泛型进行约束 -
named(String)
:经过字符串进行约束 -
named(Enum)
:经过枚举进行约束
与 named()
效果相同的还有 qualifier()
、_q()
,它们仅仅名字的差异,所以我也搞不明白为啥供给两个剩余 API 。
5. 第三方类注入
用法较前面没有不同,javascript略~
6. 泛型的处理
假定事务中不想重复创立容器类,需求创立后持续运用,可android手机以这么写:
val mojava模拟器dule = modul接口的界说e {
single(接口和抽象类的差异named("Ints")) { ArrayList<Inandroid下载t>() }
single(named("Strings")) { ArrayList&landroid是什么手机牌子t;String>() }
}
有必要运用 Qualif接口和抽象类的差异ier
进行约束。
7.APP Scope
效果域,能够赋接口自动化予我们运用的注入一段生命周期,用完手动关闭。
// 界说效果域内的装备
val module = module {
scope<String接口卡>{
scoped { Obj() }
// ...
}
}
class Test {
private val scope = GlobalContext.接口crc过错计数get().getOrCreateScope<String>("")
private val obj = scope.get<Obj>()
fun recycle() {
scope.close()
}
}
装备 Sc接口测验ope 时需求指定 scopeId 、scoAndroidpeName(可运用 Qualifier 或泛型android平板电脑价格) ,运用注入时首要创立出 scope ,有一javaee下函数可供获取:
-
createScope()
:创立效果域接口自动化 -
getScope
:获取效果域,如不存在会报失常 -
getOrCreateScope
:获取效果域,如不存在会创立并回来
8. Properapp下载ties
可经过接口类型 Koin 增修正查暂时键值对,有一下 API :
-
getProperty
:依据 key 获取 valu接口测验e接口文档 -
setPrandroid体系operty
:设置键值对 -
deleteProperty
:删去键值对
9. 其他有用的 API
-
loadModules
:可加载装备模块 -
unloa接口crc过错计数dModules
:可卸载装备模块 -
KoinComponent
:完成这个接口获得 Koiandroid什么意思n KTX 功用 -
Kandroid的drawable类oinScopeComponent
:KoinComponent
的子接口,完成此接口可运用 Koin Scope KTX 功用