无法在Android中使用Room创建数据库。

huangapple go评论67阅读模式
英文:

Unable to create a database using room in android

问题

我正在尝试使用Room创建一个用于存储单词卡片的数据库。我确信我已经完成了所有必要的代码,但是当我运行我的应用程序并使用Database Inspector时,它显示没有可显示的内容。我不确定为什么。

实体

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "flashcards")
data class Flashcard(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val question: String,
    val answer: String
)

数据访问对象(DAO)

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import kotlinx.coroutines.flow.Flow

@Dao
interface FlashcardDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(flashcard: Flashcard)

    @Update
    suspend fun update(flashcard: Flashcard)

    @Delete
    suspend fun delete(flashcard: Flashcard)

    @Query("SELECT * FROM flashcards WHERE id = :id")
    fun getFlashcard(id: Int): Flow<Flashcard>

    @Query("SELECT * FROM flashcards")
    fun getAllFlashcards(): Flow<List<Flashcard>>
}

数据库类

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

@Database(
    entities = [Flashcard::class],
    version = 1,
    exportSchema = false
)
abstract class FlashcardDatabase: RoomDatabase() {
    abstract fun flashcardDao(): FlashcardDao

    companion object {
        @Volatile
        private var Instance: FlashcardDatabase? = null
        fun getDatabase(context: Context): FlashcardDatabase {
            return Instance ?: synchronized(this) {
                Room.databaseBuilder(context, FlashcardDatabase::class.java, "flashcard_database")
                    .fallbackToDestructiveMigration()
                    .build()
                    .also { Instance = it }
            }
        }
    }
}

仓库接口

interface FlashCardsRepository {
    fun getAllFlashcardsStream(): Flow<List<Flashcard>>
    fun getFlashcardStream(id: Int): Flow<Flashcard?>
    suspend fun insertFlashcard(flashcard: Flashcard)
    suspend fun deleteFlashcard(flashcard: Flashcard)
    suspend fun updateFlashcard(flashcard: Flashcard)
}

仓库实现类

import kotlinx.coroutines.flow.Flow

class OfflineFlashcardsRepository(private val flashcardDao: FlashcardDao) : FlashCardsRepository {
    override fun getAllFlashcardsStream(): Flow<List<Flashcard>> = flashcardDao.getAllFlashcards()
    override fun getFlashcardStream(id: Int): Flow<Flashcard?> = flashcardDao.getFlashcard(id)
    override suspend fun insertFlashcard(flashcard: Flashcard) = flashcardDao.insert(flashcard = flashcard)
    override suspend fun updateFlashcard(flashcard: Flashcard) = flashcardDao.update(flashcard = flashcard)
    override suspend fun deleteFlashcard(flashcard: Flashcard) = flashcardDao.delete(flashcard = flashcard)
}

应用容器(用于依赖注入)

import android.content.Context

interface AppContainer {
    val flashCardsRepository: FlashCardsRepository
}

class AppDataContainer(private val context: Context): AppContainer {
    override val flashCardsRepository: FlashCardsRepository by lazy {
        OfflineFlashcardsRepository(FlashcardDatabase.getDatabase(context).flashcardDao())
    }
}

创建数据库实例的Flashcard应用程序的onCreate()方法(我已经将此应用程序添加到清单文件中)

import android.app.Application
import com.example.flashcardapp.data.AppContainer
import com.example.flashcardapp.data.AppDataContainer

class FlashcardApplication: Application() {
    lateinit var container: AppContainer
    override fun onCreate() {
        super.onCreate()
        container = AppDataContainer(this)
    }
}

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:name=".FlashcardApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.FlashcardApp"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.FlashcardApp">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

数据库检查器显示的内容
无法在Android中使用Room创建数据库。

英文:

I am trying to create a database to store flashcards using Room. I'm sure I have completed all the necessary code, however, when I run my application and use the Database Inspector, it says that there is nothing to show. I'm not sure why.

Entity

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = &quot;flashcards&quot;)
data class Flashcard(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val question: String,
    val answer: String
)

Data Access Objects

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import kotlinx.coroutines.flow.Flow
@Dao
interface FlashcardDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(flashcard: Flashcard)

    @Update
    suspend fun update(flashcard: Flashcard)

    @Delete
    suspend fun delete(flashcard: Flashcard)

    @Query(&quot;SELECT * FROM flashcards WHERE id = :id&quot;)
    fun getFlashcard(id: Int): Flow&lt;Flashcard&gt;

    @Query(&quot;SELECT * FROM flashcards&quot;)
    fun getAllFlashcards(): Flow&lt;List&lt;Flashcard&gt;&gt;

}

Database Class

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

@Database(
    entities = [Flashcard::class],
    version = 1,
    exportSchema = false
)
abstract class FlashcardDatabase: RoomDatabase() {
    abstract fun flashcardDao(): FlashcardDao

    companion object {
        @Volatile
        private var Instance: FlashcardDatabase? = null
        fun getDatabase(context: Context): FlashcardDatabase {
            return Instance ?: synchronized(this) {
                Room.databaseBuilder(context, FlashcardDatabase::class.java, &quot;flashcard_database&quot;)
                    .fallbackToDestructiveMigration()
                    .build()
                    .also { Instance = it }
            }
        }
    }
}

Repository Interface

interface FlashCardsRepository {
    fun getAllFlashcardsStream(): Flow&lt;List&lt;Flashcard&gt;&gt;
    fun getFlashcardStream(id: Int): Flow&lt;Flashcard?&gt;
    suspend fun insertFlashcard(flashcard: Flashcard)
    suspend fun deleteFlashcard(flashcard: Flashcard)
    suspend fun updateFlashcard(flashcard: Flashcard)

}

Repository implementation class

import kotlinx.coroutines.flow.Flow

class OfflineFlashcardsRepository(private val flashcardDao: FlashcardDao) : FlashCardsRepository {
    override fun getAllFlashcardsStream(): Flow&lt;List&lt;Flashcard&gt;&gt; = flashcardDao.getAllFlashcards()
    override fun getFlashcardStream(id: Int): Flow&lt;Flashcard?&gt; = flashcardDao.getFlashcard(id)
    override suspend fun insertFlashcard(flashcard: Flashcard) = flashcardDao.insert(flashcard = flashcard)
    override suspend fun updateFlashcard(flashcard: Flashcard) = flashcardDao.update(flashcard = flashcard)
    override suspend fun deleteFlashcard(flashcard: Flashcard) = flashcardDao.delete(flashcard = flashcard)

}

App container (For dependency injections)

import android.content.Context

interface AppContainer {
    val flashCardsRepository: FlashCardsRepository
}

class AppDataContainer(private val context: Context): AppContainer {
    override val flashCardsRepository: FlashCardsRepository by lazy {
        OfflineFlashcardsRepository(FlashcardDatabase.getDatabase(context).flashcardDao())
    }

}

Flashcard Application to create an instance of the database onCreate() (I have already added this application to the manifest file)

import android.app.Application
import com.example.flashcardapp.data.AppContainer
import com.example.flashcardapp.data.AppDataContainer

class FlashcardApplication: Application() {
    lateinit var container: AppContainer
    override fun onCreate() {
        super.onCreate()
        container = AppDataContainer(this)
    }
}

Manifest File

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;&gt;

    &lt;application
        android:name=&quot;.FlashcardApplication&quot;
        android:allowBackup=&quot;true&quot;
        android:dataExtractionRules=&quot;@xml/data_extraction_rules&quot;
        android:fullBackupContent=&quot;@xml/backup_rules&quot;
        android:icon=&quot;@mipmap/ic_launcher&quot;
        android:label=&quot;@string/app_name&quot;
        android:roundIcon=&quot;@mipmap/ic_launcher_round&quot;
        android:supportsRtl=&quot;true&quot;
        android:theme=&quot;@style/Theme.FlashcardApp&quot;
        tools:targetApi=&quot;31&quot;&gt;
        &lt;activity
            android:name=&quot;.MainActivity&quot;
            android:exported=&quot;true&quot;
            android:label=&quot;@string/app_name&quot;
            android:theme=&quot;@style/Theme.FlashcardApp&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;

What the Database Inspector shows
无法在Android中使用Room创建数据库。

答案1

得分: 1

你的问题可能是你实际上还没有访问数据库。

直到你尝试访问数据库之前,也就是插入/更新或读取数据之前。

仅仅创建/检索 Room 数据库的实例并不会创建数据库,实际的底层数据库的创建会被延迟到需要时(被访问时)。因此,你需要插入/更新或读取数据,然后数据库就会被创建。

英文:

Your issue could be that you haven't actually accessed the database.

That is until you attempt to access the database; i.e. insert/update or read data.

Simply creating/retrieving an instance of the Room Database does not create the database, the actual underlying database's creation is delayed until required (accessed). So you need to insert/update or read data and then the database will be created.

huangapple
  • 本文由 发表于 2023年6月16日 00:06:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76483544.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定