📜  如何在 Android 中为房间数据库使用单例模式?

📅  最后修改于: 2022-05-13 01:54:28.541000             🧑  作者: Mango

如何在 Android 中为房间数据库使用单例模式?

先决条件:

  • Android中的房间数据库
  • 单例模式

Room 是 Android 中的 Jetpack 架构组件之一。这在 SQLite 数据库上提供了一个抽象层,用于在本地保存和执行对持久数据的操作。 Google 推荐使用 SQLite 数据库,尽管 SQLite API 更强大,但它们相当低级,需要花费大量时间和精力来使用。但是 Room 使创建数据库和对其执行操作的一切变得简单明了。单例模式是最简单的设计模式之一。有时我们只需要我们类的一个实例,例如多个对象共享的单个 DB 连接,因为为每个对象创建单独的 DB 连接可能成本很高。类似地,应用程序中可以有一个配置管理器或错误管理器来处理所有问题,而不是创建多个管理器。简而言之,当我们需要实例化一个类的单个实例时,我们使用单例模式。我们以这样一种方式定义一个类,即只能创建一个实例。

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!

在Android开发中我们可以在哪里使用单例模式?

我们可以在 Android 中使用单例模式的一些示例是:

  • 当我们使用 Room 数据库时,我们在整个应用程序中只需要一个 Room Database 类的实例。拥有数据库实例的数量可能会导致内存泄漏。因此我们在数据库中使用单例模式。
  • 在 MVVM 架构中,当我们创建 Repository 时,我们只需要一个 Instance,因为在整个应用程序执行过程中 Repository 类中没有任何变化。

在其他情况下,我们更喜欢使用单例模式。在本文中,我们将重点介绍如何在 android 中使用单例模式。由于我们已经有了在数据库中使用单例模式的想法,现在我们将进一步进行实现。



执行

在这里,我们将使用单例模式实现 Room 数据库(假设一个数据库来存储联系人)。

  • 首先,我们将定义数据实体。
  • 它将是一个数据类,让我们给它一个名字Contact.kt

请参阅以下代码以供参考。

Kotlin
import androidx.room.Entity
import androidx.room.PrimaryKey
  
@Entity(tableName = "contact")
data class Contact(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val name: String,
    val phoneNum: String
)


Kotlin
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
  
@Dao
interface ContactDao {
    @Insert
    fun insert(contact: Contact)
  
    @Query("Select * From contact")
    fun getContact():List
}


Kotlin
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
  
@Database(entities = [Contact::class], version = 1)
abstract class ContactDatabase : RoomDatabase() {
    abstract fun contactDao(): ContactDao
  
    companion object {
        private var INSTANCE: ContactDatabase? = null
        fun getDatabase(context: Context): ContactDatabase {
            if (INSTANCE == null) {
                synchronized(this) {
                    INSTANCE =
                        Room.databaseBuilder(context,ContactDatabase::class.java, "contact_database")
                            .build()
                }
            }
            return INSTANCE!!
        }
    }
}


(autoGenerate = true) 用于在添加新数据时自动增加到 id。

  • 然后我们需要创建Dao。
  • Dao 是一个接口,所以不需要在里面定义方法。 Room 负责执行这些方法。
  • Dao 用于访问数据库中的数据对象。

请参阅以下代码以供参考。

科特林

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
  
@Dao
interface ContactDao {
    @Insert
    fun insert(contact: Contact)
  
    @Query("Select * From contact")
    fun getContact():List
}
  • 现在我们将创建数据库类,它是应用程序持久化数据的主要访问点。
  • 它是一个抽象类,它继承了 RoomDatabase。这里我们实现了单例模式。

请参阅以下代码以供参考。

科特林

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
  
@Database(entities = [Contact::class], version = 1)
abstract class ContactDatabase : RoomDatabase() {
    abstract fun contactDao(): ContactDao
  
    companion object {
        private var INSTANCE: ContactDatabase? = null
        fun getDatabase(context: Context): ContactDatabase {
            if (INSTANCE == null) {
                synchronized(this) {
                    INSTANCE =
                        Room.databaseBuilder(context,ContactDatabase::class.java, "contact_database")
                            .build()
                }
            }
            return INSTANCE!!
        }
    }
}
  • 在创建 Database 类的实例时,我们使用了一个伴随对象来直接访问 getDatabase() 方法。
  • 我们使用了一个同步块来防止来自不同线程的多次调用。

因此,只要您想在 Room 数据库中使用单例模式,这个伴随对象就很常见。