Koin 依赖注入深度解析:Single、Factory 与 Scoped 到底怎么选?

在 Kotlin 的世界里,Koin 以其"无反射、极简 DSL"的特性让开发者倍感幸福。但要用好 Koin,理解其三大核心定义类型:single 、factory 与 scoped 是必修课。


一、 single:全局唯一的单例 (Singleton)

single 是 Koin 中最常用的定义方式。

  • 本质 :在整个 Koin 容器的生命周期内(通常是应用的生命周期),该定义的实例只会被创建一次。后续所有的注入请求都会返回同一个对象。

  • 生命周期:与应用进程共存亡。

  • 适用场景:

    • Repository 层:数据仓库通常不需要重复创建。
    • 网络模块:如 Retrofit 实例、OkHttpClient。
    • 本地数据库:如 Room 数据库实例。

代码示例:

Kotlin

java 复制代码
val appModule = module {
    // 整个应用运行期间,只有一个 UserRepository 实例
    single { UserRepository(get()) }
}

二、 factory:按需创建的工厂 (Factory)

与 single 相反,factory 每次都会给你提供一个"全新的"对象。

  • 本质 :每次进行注入(通过 inject() 或 get())时,Koin 都会执行一次代码块,创建一个新的实例。

  • 生命周期:Koin 不负责保存这个实例,它的生命周期由调用者决定(例如被赋值给某个局部变量)。

  • 适用场景:

    • 临时的 UI 逻辑类:不需要持久化状态的小工具。
    • 具有状态的对象:你不希望不同页面共享同一个状态的对象。

代码示例:

Kotlin

java 复制代码
val appModule = module {
    // 每次注入都会创建一个新的 Presenter 实例
    factory { UserPresenter(get()) }
}

三、 scoped:受控的作用域 (Scoped)

这是 Koin 中最强大但也最容易被误解的部分。它介于 single 和 factory 之间。

  • 本质:实例在一个特定的**作用域(Scope)**内是唯一的。当作用域开启时创建,当作用域关闭(如 Activity 销毁)时,该实例也会随之销毁。

  • 生命周期:绑定到特定的组件生命周期。

  • 适用场景:

    • 分步表单/向导界面:在 3 个 Fragment 之间共享数据,但一旦退出该流程,数据应立即清除。
    • Activity 专有数据:只在某个特定页面及其内部子组件中共享。

代码示例:

Kotlin

java 复制代码
val appModule = module {
    // 定义一个作用域
    scope<MyActivity> {
        // 在 MyActivity 的生命周期内,该实例是单例
        scoped { UserSession() }
    }
}

四、 核心差异对比表

特性 single factory scoped
实例数量 全局只有一个 每次请求都有一个新实例 作用域内唯一
内存占用 持续占用,直到应用关闭 瞬时占用,随用随关 随作用域生命周期释放
实例共享 全局共享 不共享 仅在当前作用域内共享
推荐用途 数据库、API 客户端、Repo 工具类、瞬时数据处理 页面私有逻辑、分步任务流

五、 避坑与最佳实践

  1. 关于 ViewModel :在 Android 中,Koin 提供了专用的 viewModel { ... } 关键字。它的行为类似于 factory,但由系统的 ViewModelProvider 托管,确保在配置更改(如旋转屏幕)时实例不被销毁。
  2. 避免滥用 single :虽然 single 很省事,但如果把太多具有状态的逻辑类定义为单例,会导致内存积压,甚至出现"退出登录后数据未清理"的诡异 Bug。
  3. Scoped 的自动释放 :在 Android 中使用 scoped 时,建议配合 ActivityScope 或 FragmentScope 的扩展,这样 Koin 能在组件 onDestroy() 时自动帮你回收资源,避免内存泄漏。
相关推荐
驰骋工作流10 小时前
流程时效考核的表结构:从待办时限到 WF_CH 考核结果驰骋BPM驰骋低代码低代码工作流引擎
android·低代码·rxjava
传奇开心果编程12 小时前
【Flutter踩坑排雷】第7课:巨型 build 函数坑|全部 UI 写在同一个 build,维护难、隐性异常
android·flutter·ios·移动开发·跨平台·dart·声明式ui
我是唐青枫12 小时前
Kotlin Delegation 委托详解
开发语言·kotlin
方白羽15 小时前
Android 双开环境底层剖析与风控检测落地
android·安全·app
weixin_5633714716 小时前
Android Studio 2024 版 Device Explorer 打开方法
android·ide·android studio
AIsoft_868918 小时前
职场音频文件怎么整理?录音APP有哪些用法
android·音视频
booboosui18 小时前
第一批个人 Agent 用户正在卸载,问题不在模型,在它住在哪儿
android
洞见前行19 小时前
点击图标到内容出现,你的 App 在这几秒里做了什么:Android 冷启动全链路优化实战
android·性能优化·android studio
凯基迪科技19 小时前
芯片UID绑定修改 加密与逆向修改思路分析
android
Liben20 小时前
Weex开发踩坑记录
android·前端·ios