Android转KMP项目:Room与Retrofit替代方案及数据保留方法
问题解答:Android转KMP替代Room/Retrofit及数据迁移方案
一、Room与Retrofit在KMP中的限制
Room依赖APT生成Java代码,仅支持Android平台,无法在KMP的iOS目标中运行;Retrofit核心虽支持Kotlin,但默认配套的Converter、Adapter(如Gson、RxJava)多为Android专属,即便强行适配,跨平台生态支持也不完善,不适合作为KMP跨层的首选方案。
二、替代方案选择
1. 网络层:Ktor Client
- 原生支持KMP,Android、iOS等多平台API完全一致
- 内置Kotlinx Serialization序列化器,无需依赖Android专属库
- 天然支持协程,与Kotlin生态无缝融合
- 示例代码:
// 共享模块定义HttpClient val httpClient = HttpClient { install(JsonFeature) { serializer = KotlinxSerializer() } } // 定义API接口 interface ApiService { @Get("/users") suspend fun getUsers(): List<User> } // 发起请求 val api = httpClient.create<ApiService>() val users = api.getUsers()
2. 数据库层:SQLDelight
- Square出品,为各平台生成原生代码(Android用SQLite,iOS适配原生SQLite)
- 基于SQL语句生成类型安全的Kotlin API,规避Room的APT限制
- 支持版本迁移,逻辑与Room类似但更灵活
备选:Realm Kotlin SDK
- 跨平台NoSQL数据库,自带数据同步功能
- 适合无需SQL的场景,API更简洁
三、从Room迁移到SQLDelight(不丢失数据)
步骤1:导出Room数据库Schema
在Android项目build.gradle中开启Schema导出:
android { defaultConfig { javaCompileOptions { annotationProcessorOptions { arguments += ["room.schemaLocation": "$projectDir/schemas".toString()] } } } }
编译后在schemas目录获取各版本的SQL创建语句。
步骤2:编写SQLDelight Schema
在共享模块创建.sq文件,完全复刻Room导出的表名、字段名、类型,配置SQLDelight插件指定数据库名称和版本。
步骤3:编写迁移脚本
SQLDelight通过Migration类实现版本升级,示例:
val migration1To2 = object : Migration(1, 2) { override fun migrate(database: SqlDriver) { database.execute(null, "ALTER TABLE user ADD COLUMN age INTEGER", emptyArray()) } }
步骤4:Android端复用原有数据库文件
SQLDelight的AndroidSqliteDriver可直接使用原Room的数据库路径,初始化时传入迁移脚本:
val driver = AndroidSqliteDriver( schema = AppDatabase.Schema, context = context, name = "原Room数据库名称", migrations = listOf(migration1To2) ) val database = AppDatabase(driver)
启动时会自动完成迁移,原有数据可直接访问。
步骤5:验证数据完整性
迁移完成后,通过SQLDelight API查询数据,确认所有原有记录正常读取。
四、额外注意事项
- 若坚持用Retrofit,可仅在Android模块保留,共享层定义接口,iOS模块用URLSession或Ktor实现,但会增加维护成本,不如统一用Ktor Client
- 迁移前务必备份测试环境数据库文件,避免数据丢失
- 复杂Room查询需手动转换为SQLDelight的SQL语句,确保逻辑一致
内容的提问来源于stack exchange,提问作者josef atef
相关产品推荐
相关产品推荐

