ห้อง (Kotlin Multiplatform)

ไลบรารีการคงอยู่ของ Room มีเลเยอร์การแยกข้อมูลเหนือ SQLite เพื่อให้ เข้าถึงฐานข้อมูลได้อย่างมีประสิทธิภาพมากขึ้นในขณะที่ใช้ประโยชน์จากความสามารถทั้งหมดของ SQLite หน้านี้มุ่งเน้นการใช้ Room ในโปรเจ็กต์ Kotlin Multiplatform (KMP) ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ Room ได้ที่บันทึกข้อมูลในฐานข้อมูลของเครื่องโดยใช้ Room หรือตัวอย่างอย่างเป็นทางการ

ตั้งค่าทรัพยากร Dependency

หากต้องการตั้งค่า Room ในโปรเจ็กต์ KMP ให้เพิ่มการอ้างอิงสำหรับอาร์ติแฟกต์ในไฟล์ build.gradle.kts สำหรับโมดูล KMP

กำหนดทรัพยากร Dependency ในไฟล์ libs.versions.toml ดังนี้

[versions]
room = "2.7.2"
sqlite = "2.5.2"
ksp = "<kotlinCompatibleKspVersion>"

[libraries]
androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }

# Optional SQLite Wrapper available in version 2.8.0 and higher
androidx-room-sqlite-wrapper = { module = "androidx.room:room-sqlite-wrapper", version.ref = "room" }

[plugins]
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
androidx-room = { id = "androidx.room", version.ref = "room" }

เพิ่มปลั๊กอิน Gradle ของ Room เพื่อกำหนดค่าสคีมาของ Room และปลั๊กอิน KSP

plugins {
  alias(libs.plugins.ksp)
  alias(libs.plugins.androidx.room)
}

เพิ่มการอ้างอิงรันไทม์ของ Room และไลบรารี SQLite ที่รวมไว้

commonMain.dependencies {
  implementation(libs.androidx.room.runtime)
  implementation(libs.androidx.sqlite.bundled)
}

// Optional when using Room SQLite Wrapper
androidMain.dependencies {
  implementation(libs.androidx.room.sqlite.wrapper)
}

เพิ่มการพึ่งพา KSP ลงในบล็อก root dependencies โปรดทราบว่าคุณต้องเพิ่มเป้าหมายทั้งหมดที่แอปใช้ ดูข้อมูลเพิ่มเติมได้ที่ KSP พร้อม Kotlin Multiplatform

dependencies {
    add("kspAndroid", libs.androidx.room.compiler)
    add("kspIosSimulatorArm64", libs.androidx.room.compiler)
    add("kspIosX64", libs.androidx.room.compiler)
    add("kspIosArm64", libs.androidx.room.compiler)
    // Add any other platform target you use in your project, for example kspDesktop
}

กำหนดไดเรกทอรีสคีมาของห้อง ดูข้อมูลเพิ่มเติมได้ที่ตั้งค่าตำแหน่งสคีมา โดยใช้ปลั๊กอิน Gradle ของ Room

room {
    schemaDirectory("$projectDir/schemas")
}

กำหนดคลาสฐานข้อมูล

คุณต้องสร้างคลาสฐานข้อมูลที่ใส่คำอธิบายประกอบด้วย @Database พร้อมกับ DAO และเอนทิตีภายในชุดแหล่งที่มาทั่วไปของโมดูล KMP ที่แชร์ การวางคลาสเหล่านี้ในแหล่งที่มาทั่วไปจะช่วยให้แชร์คลาสในแพลตฟอร์มเป้าหมายทั้งหมดได้

// 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("KotlinNoActualForExpect")
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase> {
    override fun initialize(): AppDatabase
}

เมื่อประกาศออบเจ็กต์ expect ที่มีอินเทอร์เฟซ RoomDatabaseConstructor คอมไพเลอร์ Room จะสร้างการใช้งาน actual Android Studio อาจแสดงคำเตือนต่อไปนี้ ซึ่งคุณสามารถ ระงับได้ด้วย @Suppress("KotlinNoActualForExpect")

Expected object 'AppDatabaseConstructor' has no actual declaration in module`

จากนั้นให้กำหนดอินเทอร์เฟซ DAO ใหม่ หรือย้ายอินเทอร์เฟซที่มีอยู่ไปยัง commonMain

// shared/src/commonMain/kotlin/TodoDao.kt

@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<TodoEntity>>
}

กำหนดหรือย้ายเอนทิตีไปยัง commonMain โดยทำดังนี้

// shared/src/commonMain/kotlin/TodoEntity.kt

@Entity
data class TodoEntity(
  @PrimaryKey(autoGenerate = true) val id: Long = 0,
  val title: String,
  val content: String
)

สร้างเครื่องมือสร้างฐานข้อมูลเฉพาะแพลตฟอร์ม

คุณต้องกำหนดตัวสร้างฐานข้อมูลเพื่อสร้างอินสแตนซ์ Room ในแต่ละแพลตฟอร์ม ส่วนนี้ เป็นส่วนเดียวของ API ที่ต้องอยู่ในชุดแหล่งข้อมูลเฉพาะแพลตฟอร์ม เนื่องจากความแตกต่างของ File System API

Android

ใน Android โดยปกติแล้วจะรับตำแหน่งฐานข้อมูลผ่าน API ของ Context.getDatabasePath() หากต้องการสร้างอินสแตนซ์ฐานข้อมูล ให้ระบุ Context พร้อมกับเส้นทางฐานข้อมูล

// shared/src/androidMain/kotlin/Database.android.kt

fun getDatabaseBuilder(context: Context): RoomDatabase.Builder<AppDatabase> {
  val appContext = context.applicationContext
  val dbFile = appContext.getDatabasePath("my_room.db")
  return Room.databaseBuilder<AppDatabase>(
    context = appContext,
    name = dbFile.absolutePath
  )
}

iOS

หากต้องการสร้างอินสแตนซ์ฐานข้อมูลใน iOS ให้ระบุเส้นทางฐานข้อมูลโดยใช้ NSFileManager ซึ่งมักจะอยู่ใน NSDocumentDirectory

// shared/src/iosMain/kotlin/Database.ios.kt

fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
    val dbFilePath = documentDirectory() + "/my_room.db"
    return Room.databaseBuilder<AppDatabase>(
        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)
}

JVM (เดสก์ท็อป)

หากต้องการสร้างอินสแตนซ์ฐานข้อมูล ให้ระบุเส้นทางฐานข้อมูลโดยใช้ Java หรือ Kotlin API

// shared/src/jvmMain/kotlin/Database.desktop.kt

fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
    val dbFile = File(System.getProperty("java.io.tmpdir"), "my_room.db")
    return Room.databaseBuilder<AppDatabase>(
        name = dbFile.absolutePath,
    )
}
แทนได้

สร้างอินสแตนซ์ฐานข้อมูล

เมื่อได้รับ RoomDatabase.Builder จากตัวสร้างเฉพาะแพลตฟอร์มแล้ว คุณจะกำหนดค่าฐานข้อมูล Room ที่เหลือในโค้ดทั่วไป พร้อมกับการสร้างอินสแตนซ์ฐานข้อมูลจริงได้

// shared/src/commonMain/kotlin/Database.kt

fun getRoomDatabase(
    builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
  return builder
      .setDriver(BundledSQLiteDriver())
      .setQueryCoroutineContext(Dispatchers.IO)
      .build()
}

เลือกไดรเวอร์ SQLite

โค้ดตัวอย่างก่อนหน้านี้เรียกใช้ฟังก์ชันบิลเดอร์ setDriver เพื่อกำหนดว่าฐานข้อมูล Room ควรใช้ไดรเวอร์ SQLite ใด ไดรเวอร์เหล่านี้จะแตกต่างกันไปตาม แพลตฟอร์มเป้าหมาย ข้อมูลโค้ดก่อนหน้านี้ใช้ BundledSQLiteDriver นี่คือไดรเวอร์ที่แนะนำซึ่งรวม SQLite ที่คอมไพล์จากแหล่งที่มา ซึ่ง ให้ SQLite เวอร์ชันที่สอดคล้องและเป็นปัจจุบันมากที่สุดในทุกแพลตฟอร์ม

หากต้องการใช้ SQLite ที่ระบบปฏิบัติการมีให้ ให้ใช้ setDriver API ในชุดแหล่งที่มาเฉพาะแพลตฟอร์มที่ระบุไดรเวอร์เฉพาะแพลตฟอร์ม ดูคำอธิบายการติดตั้งไดรเวอร์ที่พร้อมใช้งานได้ที่ การติดตั้งไดรเวอร์ คุณใช้ข้อมูลต่อไปนี้อย่างใดอย่างหนึ่งได้

หากต้องการใช้ NativeSQLiteDriver คุณต้องระบุตัวเลือก Linker -lsqlite3 เพื่อให้แอป iOS ลิงก์กับ SQLite ของระบบแบบไดนามิก

// 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")
        }
    }
}

ตั้งค่าบริบทของโครูทีน (ไม่บังคับ)

คุณสามารถกำหนดค่าออบเจ็กต์ RoomDatabase ใน Android ด้วยตัวดำเนินการแอปพลิเคชันที่ใช้ร่วมกันโดยใช้ RoomDatabase.Builder.setQueryExecutor() เพื่อดำเนินการฐานข้อมูลได้ (ไม่บังคับ)

เนื่องจาก Executor ไม่รองรับ KMP  API ของ Room จึงไม่พร้อมใช้งานใน commonMainsetQueryExecutor() แต่ต้องกำหนดค่าออบเจ็กต์ RoomDatabase ด้วย CoroutineContext ซึ่งตั้งค่าได้โดยใช้ RoomDatabase.Builder.setCoroutineContext() หากไม่ได้ตั้งค่าบริบทไว้ ออบเจ็กต์ RoomDatabase จะใช้ Dispatchers.IO เป็นค่าเริ่มต้น

การลดขนาดและการปกปิด

หากโปรเจ็กต์ย่อหรือปกปิด คุณต้องใส่กฎ ProGuard ต่อไปนี้เพื่อให้ Room ค้นหาการติดตั้งใช้งานที่สร้างขึ้นของคำจำกัดความฐานข้อมูลได้

-keep class * extends androidx.room.RoomDatabase { <init>(); }

ย้ายข้อมูลไปยัง Kotlin Multiplatform

เดิมที Room ได้รับการพัฒนาเป็นไลบรารี Android และต่อมาได้ย้ายข้อมูลไปยัง KMP โดยมุ่งเน้นที่ความเข้ากันได้ของ API Room เวอร์ชัน KMP จะแตกต่างกันเล็กน้อย ระหว่างแพลตฟอร์มและจากเวอร์ชันเฉพาะของ Android ความแตกต่างเหล่านี้มีรายละเอียดดังนี้

ย้ายข้อมูลจาก Support SQLite ไปยัง SQLite Driver

การใช้งาน SupportSQLiteDatabase และ API อื่นๆ ใน androidx.sqlite.db ต้องได้รับการปรับโครงสร้างใหม่ด้วย SQLite Driver API เนื่องจาก API ใน androidx.sqlite.db ใช้ได้เฉพาะใน Android (โปรดทราบว่า แพ็กเกจแตกต่างจากแพ็กเกจ KMP)

เพื่อความเข้ากันได้แบบย้อนกลับและตราบใดที่RoomDatabaseได้รับการกำหนดค่าด้วย SupportSQLiteOpenHelper.Factory (เช่น ไม่ได้ตั้งค่า SQLiteDriver) Room จะทำงานใน "โหมดความเข้ากันได้" ซึ่งทั้ง API ของ Support SQLite และ SQLite Driver จะทำงานตามที่คาดไว้ ซึ่งจะช่วยให้คุณทำการย้ายข้อมูลแบบเพิ่มทีละรายการได้ จึงไม่จำเป็นต้องแปลงการใช้งาน SQLite ทั้งหมดที่รองรับเป็นไดรเวอร์ SQLite ในการเปลี่ยนแปลงครั้งเดียว

แปลงคลาสย่อยของการย้ายข้อมูล

ต้องย้ายข้อมูลคลาสย่อยของการย้ายข้อมูลไปยังไดรเวอร์ SQLite ที่เทียบเท่า

Kotlin Multiplatform

คลาสย่อยของการย้ายข้อมูล

object Migration_1_2 : Migration(1, 2) {
  override fun migrate(connection: SQLiteConnection) {
    // …
  }
}

คลาสย่อยของข้อกำหนดการย้ายข้อมูลอัตโนมัติ

class AutoMigrationSpec_1_2 : AutoMigrationSpec {
  override fun onPostMigrate(connection: SQLiteConnection) {
    // …
  }
}

Android เท่านั้น

คลาสย่อยของการย้ายข้อมูล

object Migration_1_2 : Migration(1, 2) {
  override fun migrate(db: SupportSQLiteDatabase) {
    // …
  }
}

คลาสย่อยของข้อกำหนดการย้ายข้อมูลอัตโนมัติ

class AutoMigrationSpec_1_2 : AutoMigrationSpec {
  override fun onPostMigrate(db: SupportSQLiteDatabase) {
    // …
  }
}

การเรียกกลับของฐานข้อมูลที่แปลงแล้ว

ต้องย้ายข้อมูลการเรียกกลับของฐานข้อมูลไปยังการเรียกกลับของไดรเวอร์ SQLite

Kotlin Multiplatform

object MyRoomCallback : RoomDatabase.Callback() {
  override fun onCreate(connection: SQLiteConnection) {
    // …
  }

  override fun onDestructiveMigration(connection: SQLiteConnection) {
    // …
  }

  override fun onOpen(connection: SQLiteConnection) {
    // …
  }
}

Android เท่านั้น

object MyRoomCallback : RoomDatabase.Callback() {
  override fun onCreate(db: SupportSQLiteDatabase) {
    // …
  }

  override fun onDestructiveMigration(db: SupportSQLiteDatabase) {
    // …
  }

  override fun onOpen(db: SupportSQLiteDatabase) {
    // …
  }
}

แปลงฟังก์ชัน @RawQuery DAO

ฟังก์ชันที่มีคำอธิบายประกอบด้วย @RawQuery ซึ่งคอมไพล์สำหรับแพลตฟอร์มที่ไม่ใช่ Android จะต้องประกาศพารามิเตอร์ประเภท RoomRawQuery แทน SupportSQLiteQuery

Kotlin Multiplatform

กำหนดการค้นหาดิบ

@Dao
interface TodoDao {
  @RawQuery
  suspend fun getTodos(query: RoomRawQuery): List<TodoEntity>
}

จากนั้นจะใช้ RoomRawQuery เพื่อสร้างการค้นหาในขณะรันไทม์ได้

suspend fun AppDatabase.getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
    val query = RoomRawQuery(
        sql = "SELECT * FROM TodoEntity WHERE title = ?",
        onBindStatement = {
            it.bindText(1, title.lowercase())
        }
    )

    return todoDao().getTodos(query)
}

Android เท่านั้น

กำหนดการค้นหาดิบ

@Dao
interface TodoDao {
  @RawQuery
  suspend fun getTodos(query: SupportSQLiteQuery): List<TodoEntity>
}

จากนั้นจะใช้ SimpleSQLiteQuery เพื่อสร้างการค้นหาในขณะรันไทม์ได้

suspend fun AndroidOnlyDao.getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
  val query = SimpleSQLiteQuery(
      query = "SELECT * FROM TodoEntity WHERE title = ?",
      bindArgs = arrayOf(title.lowercase())
  )
  return getTodos(query)
}

แปลงฟังก์ชัน DAO ที่บล็อก

Room ได้รับประโยชน์จากไลบรารีแบบอะซิงโครนัส kotlinx.coroutines ที่มีฟีเจอร์มากมาย ซึ่ง Kotlin มีให้สำหรับหลายแพลตฟอร์ม เพื่อการทำงานที่ดีที่สุด เราจะบังคับใช้suspend ฟังก์ชันสำหรับ DAO ที่คอมไพล์ในโปรเจ็กต์ KMP ยกเว้น DAO ที่ใช้ใน androidMain เพื่อรักษาความเข้ากันได้แบบย้อนหลังกับ โค้ดเบสที่มีอยู่ เมื่อใช้ Room สำหรับ KMP ฟังก์ชัน DAO ทั้งหมดที่คอมไพล์สำหรับ แพลตฟอร์มที่ไม่ใช่ Android ต้องเป็นฟังก์ชัน suspend

Kotlin Multiplatform

การระงับคำค้นหา

@Query("SELECT * FROM Todo")
suspend fun getAllTodos(): List<Todo>

การระงับธุรกรรม

@Transaction
suspend fun transaction() {  }

Android เท่านั้น

การค้นหาเกี่ยวกับการบล็อก

@Query("SELECT * FROM Todo")
fun getAllTodos(): List<Todo>

การบล็อกธุรกรรม

@Transaction
fun blockingTransaction() {  }

แปลงประเภทรีแอ็กทีฟเป็น Flow

ฟังก์ชัน DAO บางอย่างไม่จำเป็นต้องเป็นฟังก์ชันระงับ ไม่ควรแปลงฟังก์ชัน DAO ที่แสดงผลประเภทรีแอกทีฟ เช่น LiveData หรือ Flowable ของ RxJava เป็นฟังก์ชันระงับ อย่างไรก็ตาม บางประเภท เช่น LiveData จะไม่รองรับ KMP ฟังก์ชัน DAO ที่มีประเภทการตอบกลับแบบรีแอกทีฟต้องได้รับการย้ายข้อมูลไปยัง โฟลว์ของโครูทีน

Kotlin Multiplatform

ประเภทรีแอ็กทีฟ Flows

@Query("SELECT * FROM Todo")
fun getTodosFlow(): Flow<List<Todo>>

Android เท่านั้น

ประเภทรีแอ็กทีฟ เช่น LiveData หรือ Flowable ของ RxJava

@Query("SELECT * FROM Todo")
fun getTodosLiveData(): LiveData<List<Todo>>

แปลง API ธุรกรรม

API ธุรกรรมของฐานข้อมูลสำหรับ Room KMP สามารถแยกความแตกต่างระหว่างธุรกรรมการเขียน (useWriterConnection) และการอ่าน (useReaderConnection) ได้

Kotlin Multiplatform

val database: RoomDatabase = 
database.useWriterConnection { transactor ->
  transactor.immediateTransaction {
    // perform database operations in transaction
  }
}

Android เท่านั้น

val database: RoomDatabase = 
database.withTransaction {
  // perform database operations in transaction
}

เขียนธุรกรรม

ใช้ธุรกรรมการเขียนเพื่อให้แน่ใจว่าการค้นหาหลายรายการจะเขียนข้อมูลแบบอะตอม เพื่อให้ผู้อ่านเข้าถึงข้อมูลได้อย่างสม่ำเสมอ คุณทำได้โดยใช้ useWriterConnection กับธุรกรรม 3 ประเภทต่อไปนี้

  • immediateTransaction: ในโหมดการบันทึกแบบเขียนล่วงหน้า (WAL) (ค่าเริ่มต้น) ธุรกรรมประเภทนี้จะรับล็อกเมื่อเริ่มต้น แต่ ผู้อ่านจะอ่านต่อไปได้ ตัวเลือกนี้เป็นตัวเลือกที่แนะนำสำหรับกรณีส่วนใหญ่

  • deferredTransaction: ธุรกรรมจะไม่ได้รับการล็อกจนกว่าจะถึงคำสั่งเขียนแรก ใช้ธุรกรรมประเภทนี้เป็นการเพิ่มประสิทธิภาพเมื่อคุณไม่แน่ใจว่าจำเป็นต้องมีการดำเนินการเขียนภายในธุรกรรมหรือไม่ ตัวอย่างเช่น หากคุณเริ่มธุรกรรมเพื่อลบเพลงจากเพลย์ลิสต์โดยระบุเพียงชื่อเพลย์ลิสต์และไม่มีเพลย์ลิสต์ดังกล่าว ระบบก็ไม่จำเป็นต้องดำเนินการเขียน (ลบ)

  • exclusiveTransaction: โหมดนี้ทำงานเหมือนกับ immediateTransactionในโหมด WAL ในโหมดบันทึกการเปลี่ยนแปลงอื่นๆ จะ ป้องกันไม่ให้การเชื่อมต่อฐานข้อมูลอื่นๆ อ่านฐานข้อมูลขณะ ทำธุรกรรม

อ่านธุรกรรม

ใช้ธุรกรรมการอ่านเพื่ออ่านจากฐานข้อมูลหลายครั้งอย่างสม่ำเสมอ เช่น เมื่อคุณมีคำค้นหาแยกกัน 2 รายการขึ้นไปและไม่ได้ใช้JOIN อนุญาตให้ใช้เฉพาะธุรกรรมที่เลื่อนการชำระเงินในการเชื่อมต่อของผู้อ่าน การพยายามเริ่มธุรกรรมแบบทันทีหรือแบบพิเศษในการเชื่อมต่อของผู้อ่านจะทำให้เกิดข้อยกเว้น เนื่องจากถือเป็นการดำเนินการ "เขียน"

val database: RoomDatabase = 
database.useReaderConnection { transactor ->
  transactor.deferredTransaction {
      // perform database operations in transaction
  }
}

ไม่พร้อมใช้งานใน Kotlin Multiplatform

API บางรายการที่พร้อมใช้งานสำหรับ Android จะไม่พร้อมใช้งานใน Kotlin Multiplatform

การเรียกกลับของคำค้นหา

API ต่อไปนี้สำหรับการกำหนดค่าการเรียกกลับของคําค้นหาไม่มีให้บริการใน common จึงไม่มีให้บริการในแพลตฟอร์มอื่นๆ ที่ไม่ใช่ Android

  • RoomDatabase.Builder.setQueryCallback
  • RoomDatabase.QueryCallback

เราตั้งใจที่จะเพิ่มการรองรับการเรียกกลับของคําค้นหาใน Room เวอร์ชันในอนาคต

API สำหรับกำหนดค่า RoomDatabase ที่มีการเรียกกลับการค้นหา RoomDatabase.Builder.setQueryCallback พร้อมกับอินเทอร์เฟซการเรียกกลับ RoomDatabase.QueryCallback ไม่พร้อมใช้งานในแพลตฟอร์มทั่วไป จึงไม่พร้อมใช้งาน ในแพลตฟอร์มอื่นๆ ที่ไม่ใช่ Android

การปิดฐานข้อมูลอัตโนมัติ

API ที่ใช้เปิดใช้การปิดอัตโนมัติหลังจากหมดเวลา RoomDatabase.Builder.setAutoCloseTimeout จะใช้ได้ใน Android เท่านั้น และใช้ไม่ได้ในแพลตฟอร์มอื่นๆ

ฐานข้อมูลที่แพ็กเกจไว้ล่วงหน้า

API ต่อไปนี้สำหรับสร้าง RoomDatabase โดยใช้ฐานข้อมูลที่มีอยู่ (เช่น ฐานข้อมูลที่แพ็กไว้ล่วงหน้า) จะไม่พร้อมใช้งานในแพลตฟอร์มทั่วไป จึงไม่พร้อมใช้งานในแพลตฟอร์มอื่นๆ นอกเหนือจาก Android API เหล่านี้ ได้แก่

  • RoomDatabase.Builder.createFromAsset
  • RoomDatabase.Builder.createFromFile
  • RoomDatabase.Builder.createFromInputStream
  • RoomDatabase.PrepackagedDatabaseCallback

เราตั้งใจที่จะเพิ่มการรองรับฐานข้อมูลที่แพ็กไว้ล่วงหน้าใน Room เวอร์ชันในอนาคต

การทำให้ใช้งานไม่ได้ในหลายอินสแตนซ์

API ที่ใช้เปิดใช้การล้างข้อมูลหลายอินสแตนซ์ RoomDatabase.Builder.enableMultiInstanceInvalidation จะใช้ได้เฉพาะใน Android และใช้ไม่ได้ในแพลตฟอร์มทั่วไปหรือแพลตฟอร์มอื่นๆ