如何创建新的 Kotlin 多平台项目:详细步骤与最佳实践

2026-02-07 0 465

在软件开发过程中,Room库的使用常常会遇到不少难题。若想使用Room的1.9.x版本,并确保其KSP处理器能够正常运行,其中涉及的操作步骤颇为复杂。许多开发者可能会在这个环节遇到困难。那么,如何才能顺利地使用Room库?接下来,我们就来详细探讨这个问题。

配置文件添加属性至关重要

<pre class="prettyprint lang-kotlin” translate=”no” dir=”ltr”>// shared/src/commonMain/kotlin/Database.kt
@Database(entities = [TodoEntity::class], version = 1)
@ConstructedBy(AppDatabaseConstructor::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun getDao(): TodoDao
}
// The Room compiler generates the `actual` implementations.
@Suppress(\"NO_ACTUAL_FOR_EXPECT\")
expect object AppDatabaseConstructor : RoomDatabaseConstructor {
override fun initialize(): AppDatabase
}
@Dao
interface TodoDao {
@Insert
suspend fun insert(item: TodoEntity)
@Query(\"SELECT count(*) FROM TodoEntity\")
suspend fun count(): Int
@Query(\"SELECT * FROM TodoEntity\")
fun getAllAsFlow(): Flow<List>
}
@Entity
data class TodoEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val title: String,
val content: String
)

运行1.9.x版本,配置文件中需加入.n=true这一属性,这是确保Room的KSP处理器能正常运行的关键步骤。若遗漏此属性,后续操作或运行时可能会遇到问题。举例来说,某开发团队在制作一款支持多平台的应用时,忽视了这一属性,尽管前期进展顺利,但在最终测试阶段,Room的KSP处理器却无法正常运作,导致他们花费了大量时间去排查,最终发现是缺少了这一属性。由此可知,在开发过程中,我们必须严格遵守对应版本的规范。

操作时,配置文件调整一处,可能影响全局。因此,在添加属性时,务必认真对待,依照官方指南严格实施,这样才能从始至终为开发过程打下坚实的基础。

数据库类与DAO的创建

构建一个带注解的数据库类及DAO是至关重要的步骤。这一环节在共享KMP模块的公共源代码中,处理实体及其相关操作。这就像建造高楼大厦的基础,若基础不稳,整座建筑将不牢固。比如,有开发者尝试开发一个大型数据交互应用,若对这部分操作不够细致,就会导致数据存储和调用出现很多问题,进而严重影响用户的使用体验。

操作时需留意Room编译器对对象的操作方式。接口声明对象时,Room编译器会自动生成相应实现。这对开发全过程至关重要。开发者需理解此机制,以便构建合理的代码架构,满足不同开发需求。

// shared/src/androidMain/kotlin/Database.kt
fun getDatabaseBuilder(ctx: Context): RoomDatabase.Builder {
  val appContext = ctx.applicationContext
  val dbFile = appContext.getDatabasePath(\"my_room.db\")
  return Room.databaseBuilder(
    context = appContext,
    name = dbFile.absolutePath
  )
}

平台针对性的Room实现

开发阶段,我们可选用实际或预期声明来构建特定平台的Room实现。此时,必须细致考量各平台的特点。比如,我们可以加入针对特定平台的DAO,这在通用代码中预先设定,再依据各平台特有的查询来指定源代码集。这样的做法能彰显出对不同平台个性化需求的适应。

// shared/src/iosMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder {
    val dbFilePath = documentDirectory() + \"/my_room.db\"
    return Room.databaseBuilder(
        name = dbFilePath,
    )
}
private fun documentDirectory(): String {
  val documentDirectory = NSFileManager.defaultManager.URLForDirectory(
    directory = NSDocumentDirectory,
    inDomain = NSUserDomainMask,
    appropriateForURL = null,
    create = false,
    error = null,
  )
  return requireNotNull(documentDirectory?.path)
}

在安卓与iOS系统里,数据库的存放方式存在显著差异。在安卓上,我们通常通过一个API来确定数据库的位置,而iOS则采用不同的方法来获取这一信息。若在开发过程中不针对不同平台进行相应的调整,就极有可能遇到系统兼容性的难题,进而使得应用在某些平台上无法顺利执行。

数据库构建器的定义

// shared/src/jvmMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder {
    val dbFile = File(System.getProperty(\"java.io.tmpdir\"), \"my_room.db\")
    return Room.databaseBuilder(
        name = dbFile.absolutePath,
    )
}

构建数据库构建器是每个平台实现Room的关键步骤。这一环节必须在平台专用的源代码中特别体现,因为各个平台的文件系统API各不相同。以开发一个电商平台应用为例,不同平台对于文件存储和调用的具体方法,直接影响了数据库构建器的配置细节。

要确保数据库构建器的设置准确,Room才能在各个平台上顺利创建实例。从最初的规划阶段到具体的操作步骤,我们必须注意不同平台间的区别,并通过调整数据库构建器的设置,确保应用在各个平台上都能稳定运行。

// shared/src/commonMain/kotlin/Database.kt
fun getRoomDatabase(
    builder: RoomDatabase.Builder
): AppDatabase {
  return builder
      .addMigrations(MIGRATIONS)
      .fallbackToDestructiveMigrationOnDowngrade()
      .setDriver(BundledSQLiteDriver())
      .setQueryCoroutineContext(Dispatchers.IO)
      .build()
}

数据库实例创建与获取

建立数据库实例需明确数据库存放位置。这一过程可通过多种编程语言的API实现路径的查询,比如Java等。获取到路径信息后,便可以构建函数,随后用通用代码对Room数据库的其他部分进行配置,并完成数据库实例的创建。比如在某社交应用的开发过程中,正是凭借准确获取的数据库路径,成功创建了数据库实例,确保了数据的有序存储和顺畅交互。

获取资源需通过正规渠道,之后方可开展后续的开发任务。这一流程环环相扣,若在获取途径或构建环节出现差错,将可能对整个数据库的建立造成影响。

函数类型与API限制问题

// shared/build.gradle.kts
kotlin {
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = \"TodoApp\"
            isStatic = true
            // Required when using NativeSQLiteDriver
            linkerOpts.add(\"-lsqlite3\")
        }
    }
}

RoomforKMP要求,非平台编译的DAO函数需为特定类型,不包括反应式返回值的类型。对于带有@注解的非平台编译函数,需指定特殊参数类型。此外,某些配置查询回调的API在特定平台上并不适用。

在金融APP的开发过程中,对数据准确性和实时性要求极高。我们必须注意,不能选用不适合目标平台的API。若忽视这些API的限制,数据处理可能会出现偏差或错误,进而影响应用的稳定性和可靠性。

各位开发者,在项目开发中,是否遇到过由于忽视平台间的差异,导致Room功能出现异常的问题?欢迎大家在评论区交流,同时也期待大家能对这篇文章给予点赞和转发支持。

// shared/src/commonMain/kotlin/MultiplatformDao.kt
@Dao
interface MultiplatformDao {
  // ERROR: Blocking function not valid for non-Android targets
  @Query(\"SELECT * FROM Entity\")
  fun blockingQuery(): List
  // OK
  @Query(\"SELECT * FROM Entity\")
  suspend fun query(): List
  // OK
  @Query(\"SELECT * FROM Entity\")
  fun queryFlow(): Flow<List>
  // ERROR: Blocking function not valid for non-Android targets
  @Transaction
  fun blockingTransaction() { // … }
  // OK
  @Transaction
  suspend fun transaction() { // … }
}

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 开发教程 如何创建新的 Kotlin 多平台项目:详细步骤与最佳实践 https://www.zuozi.net/67995.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务