Detailed explanation of the combination of Android Room database LiveData and ViewModel

Android Room is a persistence library in Android development. Applications that deal with large amounts of structured data can greatly benefit from persisting this data locally. The most common use case is to cache related data so that when the device has no internet access, the user can still browse the content offline.

The Room persistence library provides an abstraction layer on top of SQLite to allow fluent database access while taking full advantage of the power of SQLite. There are mainly the following advantages:

  • Validate SQL statements at compile time;
  • Easy-to-use annotations reduce repetitive and error-prone template code;
  • Simplified database migration path.

Why is Android Room so important in Android development?

  • Type-safe database access: Room uses annotations and compile-time checking to ensure the type safety of SQL queries.
  • Simplified database operations: Room greatly simplifies the use of SQLite databases. It provides high-level abstractions that reduce the need to write complex SQL queries.
  • Responsive data management: Room integrates well with Android architecture components such as LiveData and ViewModel, and supports reactive programming.
  • Database migration support: When the application needs to change the database structure, Room provides a convenient database migration tool.
  • Official support: Room is officially provided and maintained by Google, so its compatibility and maintainability with the Android platform are guaranteed.

Use of the Room database

(Using Room with Android Architecture Components like LiveData and ViewModel)

Room mainly consists of three components:

  • Database: contains the database holder and serves as the main access point for the underlying connections to the application's retained persistent relational data
  • Entity: used to represent tables in the database
  • Dao: Contains methods for accessing the database

The relationship between the three components is shown in the figure below

Edit toggle to center

Add picture annotations, no more than 140 words (optional)

Add dependencies Add dependencies for required artifacts in your app or module's build.gradle file:

 dependencies {
     // Room数据库依赖
    def room_version = "2.2.6"
​
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    
    // 协程依赖
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.0'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.0'
    
    //LiveData和ViewModel依赖 
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
 }

Create entity classes

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

Use id as the primary key, let its default value be 0, so that it will be automatically assigned when inserting into the database

创建Dao接口
@Dao
interface RecordDao {
​
    @Query("select * from record where title = :title")
    fun getAllRecordsByTitle(title: String): LiveData<List<Record>>
​
}

Here getAllRecords() method returns LiveData

创建Database
@Database(version = 1, entities = [Record::class])
abstract class AppDatabase : RoomDatabase() {
​
    abstract fun recordDao(): RecordDao
    
    companion object {
        private var instance: AppDatabase? = null
        // 使用单例模式
        @Synchronized
        fun getDatabase(context: Context): AppDatabase {
            instance?.let {
                return it
            }
            return Room.databaseBuilder(context.applicationContext,
                    AppDatabase::class.java, "app_database")
                .build().apply { instance = this }
        }
}

When creating the above classes, pay attention to add the corresponding annotations @Entity, @Dao, @Database

2. The use of ViewModel and LiveData In the MVVM architecture, Repository undertakes the function of coordinating local storage and network data access. Here we only use local storage

In Repository.kt, add the method

object Repository {
​
    val recordDao = AppDatabase.getDatabase(DayRecordApplication.context).recordDao()
    
    fun getAllRecordsByTitle(title: String): LiveData<List<Record>> =
        return recordDao.getAllRecordsByTitle(title)
​
}

In viewModel.kt, use Transformations for data conversion:

private val _record = MutableLiveData<String>()
​
val records: LiveData<List<Record>> = Transformations.switchMap(_records) {
    Repository.getAllRecordsByTitle(it)
}

Since database operations are time-consuming operations, it is necessary to use coroutines for asynchronous operations

fun getAllRecordsByTitle(title: String)  = viewModelScope.launch{
    _record.value = title
}

When the _record data changes, it will automatically notify the record data to update

The entire code of viewModel.kt is as follows

class viewModel : ViewModel() {
​
    private val _record = MutableLiveData<String>()
    
    val records: LiveData<List<Record>> = Transformations.switchMap(_record) {
            Repository.getAllRecordsByTitle(it)
    }
    
    fun getAllRecordsByTitle(title: String)  = viewModelScope.launch{
        _record.value = title
    }
​
}

In Activity, add Observer to observe LiveData

open class MainActivity : AppCompatActivity() {
​
    private val viewModel by lazy {
        ViewModelProvider(this).get(viewModel::class.java)
    }
    private var records = ArrayList<Record>()
    private lateinit var adapter: RecordAdapter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        adapter = RecordAdapter(requireActivity(), records)
        viewModel.records.observe(this) {
            // 当viewModel中的records数据更新时
            // 会执行此段代码,进行UI的更新
            records.clear()
            records.addAll(it)
            adapter.notifyDataSetChanged()
        }
        
        button.setOnClickListener {
            // 通知viewModel进行数据变更
            viewModel.getAllRecordsByTitle(title)
        }
        
}

When the records data in the ViewModel is changed, the adapter will be notified of the data change to update the UI. At this point, the use of Room, ViewModel, and LiveData is complete. The article mainly talks about how to use it in the database Room technology developed by Android, as well as a brief background introduction. For more detailed Android advanced technology, please refer to the module " Android Core Technology Manual " , which contains more than 30 sections and thousands of technical points. You can click to view the detailed categories.

Summarize

Android Room is a powerful database persistence solution that simplifies database access, provides type safety, and integrates with Android Architecture Components to provide convenience and maintainability for Android application data management. This makes it an indispensable tool in Android application development.

Guess you like

Origin blog.csdn.net/m0_70748845/article/details/132656236