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

如何实现Room Multiplatform alpha06中AppDatabaseConstructor的actual实现?

问题

我正在尝试实现Room Multiplatform alpha06,已经编写了带有@ConstructedBy注解的AppDatabase、expect声明的AppDatabaseConstructor,以及Movie实体和MovieDao,但不知道如何实现actual的AppDatabaseConstructor中的initialize方法,试了多种方法都失败了,希望得到帮助。

相关代码片段:

expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase>
actual object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
    override fun initialize(): AppDatabase{
        // 这里该怎么实现???
    }
}

完整代码:

import androidx.room.ConstructedBy
import androidx.room.Dao
import androidx.room.Database
import androidx.room.Entity
import androidx.room.Insert
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.RoomDatabase
import androidx.room.RoomDatabaseConstructor
import kotlinx.coroutines.flow.Flow

const val DATABASE_NAME = "movie.db"

@Database(entities = [Movie::class], version = 1)
@ConstructedBy(AppDatabaseConstructor::class)
abstract class AppDatabase : RoomDatabase() {
    abstract fun getDao(): MovieDao
}

expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase>

@Dao
interface MovieDao {
    @Insert
    suspend fun insert(item: Movie)

    @Query("SELECT count(*) FROM Movie")
    suspend fun count(): Int

    @Query("SELECT * FROM Movie")
    fun getAllAsFlow(): Flow<List<Movie>>
}

@Entity
data class Movie(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val title: String,
    val overview: String,
    val releaseDate: String,
    val poster: String,
    val backdrop: String?,
    val originalTitle: String,
    val originalLanguage: String,
    val popularity: Double,
    val voteAverage: Double,
    val isFavorite: Boolean
)
解决方案

Room Multiplatform alpha06中,RoomDatabaseConstructor的actual实现需要分平台处理,核心是调用对应平台的Room数据库构建逻辑:

Android平台实现

在androidMain源集中,使用Room标准的databaseBuilder构建数据库实例:

import android.content.Context
import androidx.room.Room

actual object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
    private lateinit var appContext: Context

    // 在Application初始化时传入上下文
    fun init(context: Context) {
        appContext = context.applicationContext
    }

    override fun initialize(): AppDatabase {
        return Room.databaseBuilder(
            appContext,
            AppDatabase::class.java,
            DATABASE_NAME
        ).build()
    }
}

配套的Application初始化代码:

import android.app.Application

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        AppDatabaseConstructor.init(this)
    }
}

iOS平台实现

在iosMain源集中,使用RoomSQLiteDriver创建数据库驱动,再实例化AppDatabase:

import androidx.room.RoomSQLiteDriver
import platform.Foundation.NSFileManager
import platform.Foundation.NSDocumentDirectory
import platform.Foundation.NSUserDomainMask
import platform.Foundation.NSUTF8StringEncoding
import platform.Foundation.stringByAppendingPathComponent

actual object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
    override fun initialize(): AppDatabase {
        val driver = RoomSQLiteDriver(AppDatabase::class, getDatabaseFilePath())
        return AppDatabase.invoke(driver)
    }

    private fun getDatabaseFilePath(): String {
        val documentsDir = NSFileManager.defaultManager.URLForDirectory(
            directory = NSDocumentDirectory,
            inDomain = NSUserDomainMask,
            appropriateForURL = null,
            create = false,
            error = null
        )?.path ?: error("无法获取iOS文档目录")
        return (documentsDir as NSString).stringByAppendingPathComponent(DATABASE_NAME)
    }
}

关键注意点

  • 确保各平台的依赖配置正确,alpha06版本的Room Multiplatform需要对应版本的room-runtime、room-compiler及room-sqlite-driver依赖
  • 数据库实例建议全局复用,避免重复调用initialize创建多个实例

内容的提问来源于stack exchange,提问作者Fer Fer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:37:39