【Jetpack】Room + ViewModel + LiveData 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )

一、Room + ViewModel + LiveData 框架使用核心要点

1、Room 框架优化分析

在上一篇博客 【Jetpack】使用 Room 框架访问 Android 平台 SQLite 数据库 ( 导入依赖 | 定义 Entity 实体类 | 定义 Dao 数据库访问对象接口 | 定义数据库实例类 ) 中 , 实现了 使用 Room 框架访问 Android 中的 SQLite 数据库的操作 , 每当数据库中的数据发生变化时 , 就需要开启线程 , 重新获取数据库中的数据 ;

为了优化上述问题 , 可以引入 LiveData 和 ViewModel ,

  • ViewModel 是 视图 View 与 数据模型 Model 之间 数据交互的 桥梁 ;
  • LiveData 是基于 ViewModel 的 , 是 对 ViewModel 数据维护的一个补充 ;

在 ViewModel 中使用了 LiveData 后 ,

先调用 LiveData#observe 函数 为 LiveData 设置 androidx.lifecycle.Observer 监听器 ,

如果 该监听器 监听到了 LiveData 数据变化 ,

直接 回调 androidx.lifecycle.Observer 监听器 的 androidx.lifecycle.Observer#onChanged 函数 ,

最终在上述回调函数中执行 查询数据库 和 更新视图 操作 ;

2、Google 官方建议的 Room + ViewModel + LiveData 架构

下图是 Google 官方 提出的 Room + ViewModel + LiveData 架构设计 建议 :

在这里插入图片描述

在这里插入图片描述

下面分析上述 架构图 中的 架构分层 ;

Model 数据模型层 :

  • 本地数据访问 : 使用 Room 框架 访问本地的 SQLite 数据库 ;
  • 远程数据访问 : 使用 Retrofit 框架 访问 远程数据源 ( Remote Data Source ) ;

Repository 层 : 该层负责 封装 Model 数据模型层 , 用于与 ViewModel 层进行交互 ;

ViewModel 视图模型层 : 该层 不与 Room 和 Retrofit 直接交互 , 而是与 Repository 层 进行交互 ; 在 ViewModel 层引入 LiveData 监听数据变化 , 如果数据发生变化则在 LiveData 设置的 androidx.lifecycle.Observer 监听器回调中 更新 View 视图 ;

View 视图层 : Activity / Fragment 负责视图显示的 系统组件 , 负责维护 Android 视图组件 , 显示的数据由 ViewModel 提供 ;

3、Room 与 LiveData 结合使用要点

对于 Room 框架使用来说 ,

  • Room 与 LiveData 结合使用 ,
  • Room 单独使用 ,

唯一的区别是 Room 框架中的 Dao 数据访问接口对象 中的 查询方法 , 其返回值类型改为 LiveData 类型 , LiveData 的泛型为 原来的查询方法的返回值类型 ;

Dao 查询方法的返回值由 List<Student> 变为 LiveData<List<Student>> ;

Room 框架中 , Entity 实体类 , Database 数据库实体类 , 定义方式保持不变 ,

  • Entity 实体类 使用 @Entity 注解修饰 , 并使用 @PrimaryKey 注解修饰主键 , 使用 @ColumnInfo 注解 修饰普通字段 , 使用 @Ignore 注解 修饰不需要的字段或方法 ;
  • Database 数据库实体类 使用 @Database 注解修饰该类 , 其中定义 获取 Dao 数据库访问对象的抽象方法 , 以及 将该抽象类设置成 单例类 , 在单例对象初始化时创建数据库 ;

在 Room 框架中的 Dao 数据库访问对象接口 的定义方式需要作出改变 , 涉及到数据库查询的 接口方法时 , 其返回值需要 返回 LiveData 类型 , 泛型设置为 List<Student> 类型 ;

    /**
     * 查询数据库表
     */
    @Query("select * from student")
    fun query(): LiveData<List<Student>>

    /**
     * 根据传入的 id 查询数据库表
     * 在注解中使用 :id 调用参数中的 id: Int
     */
    @Query("select * from student where id = :id")
    fun query(id: Int): LiveData<List<Student>>

复制

原来的方法如下 , 其查询接口的返回值是 List<Student> ;

    /**
     * 查询数据库表
     */
    @Query("select * from student")
    fun query(): List<Student>

    /**
     * 根据传入的 id 查询数据库表
     * 在注解中使用 :id 调用参数中的 id: Int
     */
    @Query("select * from student where id = :id")
    fun query(id: Int): List<Student>

复制

Room 框架的用法 , 参考 【Jetpack】使用 Room 框架访问 Android 平台 SQLite 数据库 ( 导入依赖 | 定义 Entity 实体类 | 定义 Dao 数据库访问对象接口 | 定义数据库实例类 ) 博客 ;

4、Repository 层核心要点

Repository 层负责 封装 Model 数据模型层 , 用于与 ViewModel 层进行交互 ;

因此在 Repository 中 , 需要 持有 Dao 数据访问接口对象 ;

	lateinit var dao: StudentDao

复制

而 Dao 又是通过 Database 得到的 ,

因此在 该 Repository 中需要先获取 Database 数据库实例类对象 , 然后通过 Database 获取 Dao 数据访问接口 ;

    constructor(context: Context) {
        var database = StudentDatabase.inst(context)
        this.dao = database.studentDao()
    }

复制

此外 , 还需要 在 Repository 层中 , 维护数据库的 增

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值