MVVM
Model ------ View ---ViewModel
该架构是2018年由google 推出Jetpack时提出的 组件化分层架构
看到一个新的东西是不是有点激动,是不是有一点头疼,嘿嘿
别慌,我来带你们飞,我们先来理解一下这几个层级都代表的是什么
Model ----> 我们之前使用的MVP架构的时候是不是经常看到这个?对没错就是 Model 层 用来进行数据处理(数据的增、删、改、查)
View -----> 这个是不是也很熟悉?要不要猜猜看是用来做什么的,嘿,你没猜错,就是View层 (UI 层)
ViewModel -------> 看到这个就头大了,呵,这是个什么玩意? 有View也有Model ? 会不会是连接View层和Model层的? 太对了老哥,就是这个作用
(连接View层和Model层,对数据进行加载处理的层,网络数据拉取/数据库增、删、改、查)
那么现在知道它们分别是什么作用了,好那我们来撸一个简单的MVVM
前面说到 它是发布 Jetpack 的时候顺带推出的
那么与部分Jetpack组件组合使用才能体现出它最大的优势 (组件分层架构)
可能这会你要懵了,Jetpack是什么玩意,我一直用MVP用的挺好的,为啥要用Jetpack
Jetpack的推出意在简化开发,加速应用的开发时间,编码一小时,水群七小时,难道你不心动吗?
心动不如行动,来,给你们介绍几个Jetpack 简化开发工作的组件
LiveData -------------------> 使用的是观察者模式编写的一个功能函数组件 可自动感知生命周期 可订阅通知更新UI
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion" implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"
Room --------------------> 数据库的简化使用封装组件 会进行LiveData 数据订阅从而通知LiveData 数据更新
implementation "androidx.room:room-ktx:$rootProject.roomVersion" kapt "androidx.room:room-compiler:$rootProject.roomVersion" androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
Coroutines --------------------> 协程,可以使用同步的方式书写异步方法 而 不堵塞UI进程 (使编写逻辑更清晰,代码更简洁)
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines" api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
ok 组件先介绍到这里,还有很多组件,比如Binding / Paging3 等等,这些以后再跟你们说,现在就学这些就好了,或者你们自行百度去学习
注意了,要开始了
写程序一般都会涉及 UI / 数据库 / 实体类封装
来,我们先写一个实体类定义为Word 并且利用Room 直接创建数据库
说明:
@Entity 是Room的注释属性,作用将创建数据库
tableName 是Room的数据库表明
@ColumnInfo 创建列表名
@PrimaryKey 主键 -------> 属性 utoGenerate = true 表示自动创建主键 好了实体类有了,创建增删改成接口 ,此处注意是接口,用法类似于 开源框架Greedao 创建接口WordDao
说明
@Dao 表明是数据的操作
@Insert 进行数据插入
@Query 进行数据库语句查询
好了,怎删改查接口也有了,还少一步数据创建
创建 WordRoomDatabase 继承于 RoomDatabase 通过注释定义一些数据库版本 和 其他属性
package com.nova.examplesdemo.db import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.sqlite.db.SupportSQLiteDatabase import com.nova.examplesdemo.bean.Word import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlin.reflect.KParameter /** * Created by Li * 2021/3/23 */ // Annotates class to be a Room Database with a table (entity) of the Word class @Database(entities = arrayOf(Word::class), version = 1, exportSchema = false) public abstract class WordRoomDatabase : RoomDatabase() { abstract fun wordDao(): WordDao private class WordDatabaseCallback( private val scope: CoroutineScope ) : RoomDatabase.Callback() { override fun onCreate(db: SupportSQLiteDatabase) { super.onCreate(db) INSTANCE?.let { database -> scope.launch { populateDatabase(database.wordDao()) } } } suspend fun populateDatabase(wordDao: WordDao) { // Delete all content here. wordDao.deleteAll() // Add sample words. var word = Word("Hello") wordDao.insert(word) word = Word("World!") wordDao.insert(word) // TODO: Add your own words! word = Word("TODO!") wordDao.insert(word) } } companion object { // Singleton prevents multiple instances of database opening at the // same time. @Volatile private var INSTANCE: WordRoomDatabase? = null fun getDatabase( context: Context, scope: CoroutineScope ): WordRoomDatabase { // if the INSTANCE is not null, then return it, // if it is, then create the database return INSTANCE ?: synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, WordRoomDatabase::class.java, "word_database") .addCallback(WordDatabaseCallback(scope)) .build() INSTANCE = instance // return instance instance } } } } 注意Room build()创建的时候必须传入一个回调才会激发LiveData的数据更新
现在来进行初始化,激活Room以及 WordRepository, oh 这里好像还少了一步就是创建一个中间管理类来处理 LiveData 也就是 ViewModel 层的WordRepository
该类主要是对数据进行中间层操作,至于数据的来源它是不需要操心的
激活
再来看看View层是如何和ViewModel层建立联系的
注意看 ViewModel的创建 传入了一个存储库 repository
然后通过LiveData的 observe 属性进行订阅数据的更改然后更新UI
是不是很巧妙
这里边的逻辑需要你们自己再去梳理一下,要不然有点头晕
ok,下一个
MVP
Model-View-Presenter
这个是双向的
耦合高 随着业务发展 Presenter层会越来越多使得代码结构变得复杂
MVC
Model - View - Controller
这个是单向的
耦合度低 随着业务发展 Controller 层会越来越臃肿,维护难度大
嗯,就这样,这两个架构身为几年开发的你懂的,本文主要是讲一下MVVM 的搭建以及实现的MVVM的优势
done