You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

KMP中如何通过Koin注入Android上下文到SqlDelight Driver?

解决KMP中Koin注入Android上下文给SqlDelight Driver的问题

核心调整思路

问题根源在于你在commonMain中直接启动了Koin,但Android平台需要的Context是平台专属依赖,无法在common层提供。正确的做法是将Koin的启动逻辑下放给各平台,common层只负责定义通用模块,平台层补充专属依赖后再启动Koin。

具体实现步骤

1. 修改commonMain的Koin配置

移除common中的startKoin调用,只保留模块定义和通用模块集合的提供方法:

// commonMain
expect val dbModule: Module

val repoModule = module {
    single<DbRepository> {
        DbRepository(get<SqlDriver>())
    }
}

// 提供通用模块集合,供各平台调用
fun getCommonKoinModules() = listOf(dbModule, repoModule)

2. 实现Android端的dbModule并启动Koin

在AndroidMain中实现dbModule,依赖Context创建AndroidSqliteDriver,再在Application中启动Koin并传入上下文:

AndroidMain的dbModule实现:

// androidMain
actual val dbModule: Module = module {
    single<SqlDriver> {
        AndroidSqliteDriver(
            schema = YourDatabase.Schema, // 替换为你的SqlDelight数据库Schema
            context = get<Context>(),
            name = "your_database_name.db"
        )
    }
}

Android Application类中的Koin初始化:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin {
            // 传入Android上下文
            androidContext(this@MyApp)
            // 加载common层的通用模块
            modules(getCommonKoinModules())
        }
    }
}

3. 其他平台适配(示例)

iOS端可在iosMain中实现dbModule,使用NativeSqliteDriver:

// iosMain
actual val dbModule: Module = module {
    single<SqlDriver> {
        NativeSqliteDriver(YourDatabase.Schema, "your_database_name.db")
    }
}

之后在iOS启动代码中调用startKoin加载通用模块即可。

之前尝试失败的原因

  • 尝试1:commonMain已启动Koin,Android端重复调用startKoin触发KoinAppAlreadyStartedException。
  • 尝试2:koinApplication { ... }仅创建Koin实例未启动,且未关联已有实例,导致上下文无法被获取。
  • 尝试3:加载上下文模块的时机太晚,common中启动的Koin初始化dbModule时,Context还未注入,触发MissingAndroidContextException。

内容的提问来源于stack exchange,提问作者Saher Al-Sous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:50:12