android MVVM(1)用LiveData关联VM 与 V
1.官方文档
MVVM 官方文档: https://developer.android.com/jetpack/docs/guide
ViewModel 文档: https://developer.android.com/topic/libraries/architecture/viewmodel
ViewModel保存状态: https://developer.android.com/topic/libraries/architecture/viewmodel-savedstate
LiveData 官方文档: https://developer.android.com/topic/libraries/architecture/livedata
2.android mvvm 软件架构简介
2.1 架构图示

其中数字的简单描述如下:
- View通过ViewModel获取数据对象展示,并成为它的观察者。
- ViewModel通过Model得到真正的数据对象,根据业务需求通过model修改数据
- Model 只负责数据的操作:查找、从服务器下载新数据、修改等操作。
2.2 View
- 负责数据显示、用户交互,系统交互。android系统中的Fragment 、Activity。
- 只通过ViewModel得到目标数据对象展示并成为它的观察观察者。数据对象存在LiveData<XX>中。
- 不处理业务逻辑,不打开数据库,不通过网络请求数据等.
2.3 Model
- 数据抽象,封装
- 数据存储(文件、内存、服务器、本地数据库等)、数据提取
- 为ViewModel返回真正的数据对象(LiveData<xxx>)
2.4 ViewModel
- 负责为View(View(Fragment 或 Activity))准备数据
- 处理业务逻辑,不直接处理数据。
- 与模型进行通信,后者存储、网络请求数据等
2.5 LiveData
- 负责关联view与viewModel
3.LiveData
- LiveData 一系列类模板,负责关联view与viewModel,采用观察者模式、类里存放被观察的数据,它的子类如下。

- 具有系统组件(activity,fragment,service)生命周期感知能力(无需手动),系统确保只会将更新通知给活跃的观察者。
- 不支持非主线程更新
-- ::54.688 -/com.example.frgmtvm E/AndroidRuntime: FATAL EXCEPTION: Timer-
Process: com.example.frgmtvm, PID:
java.lang.IllegalStateException: Cannot invoke setValue on a background thread
at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:)
at androidx.lifecycle.LiveData.setValue(LiveData.java:)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:)
at com.example.frgmtvm.ui.main.MainViewModel$test1$.run(MainViewModel.kt:)
at java.util.TimerThread.mainLoop(Timer.java:)
at java.util.TimerThread.run(Timer.java:)
4.ViewModel
- 如果在Activity、Fragment中保存数据,容易引起3个问题:
- 当它们被销毁后再次重新构建的时候,需要重新请求加载数据,造成资源的浪费,
- 如果请求数据是异步的,在销毁Activity时,容易引起内存泄漏。
- Activity、Fragmen代码膨胀、不易维护、测试。
- android中 ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。让数据可在发生屏幕旋转等配置更改后继续留存在.
- 绝不能引用视图、
Lifecycle或可能存储对 Activity 上下文的引用的任何类 ViewModel对象应该比它们相应View对象存在的时间更长,因此ViewModel实现中不得包含对View对象的直接引用。- 如果 ViewModel 需要 Application 上下文(例如,为了查找系统服务),可以扩展 AndroidViewModel 类
- ViewModel 对象存在的时间范围是获取 ViewModel 时传递给 ViewModelProvider 的 ViewModelStoreOwner。ViewModel 将一直留在内存中,直到限定其存在时间范围的 ViewModelStoreOwner 永久消失:对于 Activity,是在 Activity finish时;而对于 Fragment,是在 Fragment detach时。
- SavedStateHandle 用来保存轻量的页面状态(key-value),可以把它们传给VIewModel 使用。
5.示例代码
完整代码:
5.1 第1步:定义Model
- User
class User {
var name = "TEST-"
var age = override fun toString(): String {
return "$name-$age"
}
} UserModel, 数据对象用LiveData系列类保存
class UserModel { var userData = MediatorLiveData<User>() init {
val user = User()
userData.value = user
} fun userFromSql() : LiveData<User> {
return userData
}
fun userFromServer() : LiveData<User>{
return userData
}
fun userFromFile() : LiveData<User>{
return userData
}
fun userFromCache() : LiveData<User>{
return userData
} fun modifyUser(age : Int,name : String){
val user = userData.value
user?.age = age
user?.name = name userData.value = user
} }
5.2 第2步:定义ViewModel
定义ViewModel,保存model对象,并提供返回数据对象的方法
class MainViewModel : ViewModel{
var userModel : UserModel = UserModel()
fun loadUser() : LiveData<User>{
val ud = userModel.userFromServer()
return ud
}
override fun onCleared() {
super.onCleared()
Log.e("MainViewModel","onCleared")
cancelTask()
}
//...
}
5.3 第3步:关联View与ViewModel
在android中,Fragment、activity被当作View
class Fragment1 : Fragment() {
lateinit var nameKey : TextView
lateinit var nameValue : EditText
lateinit var ageKey : TextView
lateinit var ageValue : TextView
val viewModel : MainViewModel by lazy { initViewModel() }
fun initViewModel() : MainViewModel{
// return ViewModelProvider(this).get(MainViewModel::class.java)
return ViewModelProvider(activity!!).get(MainViewModel::class.java)
}
fun bindViewModel(){
viewModel.loadUser().observe(viewLifecycleOwner){user->
nameValue.setText(user.name)
ageValue.setText(user.age.toString())
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
val v = inflater.inflate(R.layout.view1, container, false)
initView(v)
return v
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bindViewModel()
}
//...
}
其中:
- 第11行,绑定view与viewModel时使用的ViewModelStoreOwner是Fragment,viewModel的生命期与Fragment关联,退出Fragment后,数据失效
- 第12行,使用ViewModelStoreOwner 是 Activity,该viewModel的生命期长,退出Activity才失效,可用于多个fragment 共享数据。
- 第16行,关联view与对应的数据,当数据变化时,这里会得到通知,然后刷新界面。
android MVVM(1)用LiveData关联VM 与 V的更多相关文章
- android MVVM(2)用数据绑定关联VM 与 V
1.官方文档 https://developer.android.com/topic/libraries/data-binding/architecture 2.简介 数据绑定库 可与MVVM 架构组 ...
- Android MVVM框架RoboBinding初探
RoboBinding是一个实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架.MVVM模式是MVC模式的重要更新,使得项目结构更加的优美,易于维护以及方便 ...
- 如何构建Android MVVM 应用框架
概述 说到Android MVVM,相信大家都会想到Google 2015年推出的DataBinding框架.然而两者的概念是不一样的,不能混为一谈.MVVM是一种架构模式,而DataBinding是 ...
- (Android MVVM)使用Data Binding Library(2)
复习 上一篇学到了如何在layout.xml文件中增加元素,实现数据绑定,本篇接着学习. 事件处理 在layout.xml上绑定事件有两种方法,各有千秋. 1.方法引用 2.监听绑定 1.使用方法引用 ...
- Android Jetpack组件 - ViewModel,LiveData使用以及原理
本文涉及的源码版本如下: com.android.support:appcompat-v7:27.1.1 android.arch.lifecycle:extensions:1.1.1 android ...
- Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础
原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...
- android mvvm初探
目前google的databinding library还处在rc版,其中编译器发挥了主要作用.目前也只是在android studio开发环境中支持. mvvm能够大大降低模块间的耦合度,在开发过程 ...
- Android MVVM小结
一.概念 关于MVC.MVP与MVVM的概念就不介绍了,总之一句话,MVVM概念出现比MVP早,MVP比MVC早,作为程序员就应该去学习最新的技术不是?详细的概念介绍移步这里吧,https://www ...
- Android ToolBar自定义图标,关联DrawerLayout
Android5.0出现了一个可以代替ActionBar的控件ToolBar,使用更加灵活,一般我们使用ToolBar来和DrawerLayout配合使用,官方提供了一个开关类ActionBarDra ...
随机推荐
- Java动态代理(AOP)
目录 一.代理 1. 什么是代理? 2. 使用代理模式的作用 3. 实现代理的方式 二.静态代理 1. 模拟用户购买u盘 2. 静态代理的缺点 三.动态代理 四. JDK 动态代理 1. Invoca ...
- 记一次TOMCAT一段时间自动关闭
最近同事开发的一个项目部署上线后用过几天就TOMCAT自动关闭,并且该项目没有开通对外访问.通过阿里云监控台查看,从升级后系统内存占用上升趋势,CPU等信息没有太大变化. 打印服务器日志后发现全是线程 ...
- 系统UISearchController详解
原文链接:https://www.jianshu.com/p/aa9a153a5b58
- CSS样式大全(网络收集整理)
CSS样式大全(网络收集整理 字体属性:(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 { ...
- 每日一道 LeetCode (8):删除排序数组中的重复项和移除元素
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
- 3、Template Method 模板方法 行为型设计模式
1.了解模板方法 1.1 模式定义 定义一个操作算法中的框架,而将这些步骤延迟加载到子类中. 它的本质就是固定算法框架. 1.2 解决何种问题 让父类控制子类方法的调用顺序 模板方法模式使得子类可以不 ...
- 基于OpenSIPS做注册服务下,场景A打B,一方发起BYE挂断后收到500,另一方无法挂断的问题
基于OpenSIPS做注册服务下,场景A打B,一方发起BYE挂断后收到500,另一方无法挂断的问题 最近在工作中遇到一个看似很奇怪的,排除起来很费劲,但最后的解决方式又及其简单的问题,下面我们 ...
- 谈谈对Java平台的理解
从我第一次接触Java的时候,老师就说"Write once,run anywhere",这句话虽然听起来有一点太过于形式主义,但是也突出了它的特点.那么,现在的我们应该总结一下和 ...
- JS学习第四天
循环语句 while(){ }: while :先判断再执行,如果while的条件结果为false,那么执行语句块中代码一句都不走 do(){ }while; do while:先执行代码块中的语 ...
- Azure认知服务之表格识别器
认知服务 Azure 认知服务的目标是帮助开发人员创建可以看.听.说.理解甚至开始推理的应用程序. Azure 认知服务中的服务目录可分为五大主要支柱类别:视觉.语音.语言.Web 搜索和决策.开发人 ...