如何实现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
相关产品推荐
相关产品推荐

