ViewModel:

负责为关联UI(activity/fragment)进行数据管理,业务逻辑处理。不直接持有view引用,不对UI进行访问调用操作

对外通过暴露Livedata方式响应处理结果

LiveData:

可感知组件生命周期、被观察的数据源,在数据发生改变时进行通知提醒

ViewModel处理数据后使用LiveData通知到observer数据已变更,

Lifecycle:
对象or组件生命周期状态定义接口,实现子类LifecycleRegistry。包含LifeCycleOwer和LifecycleObserver,分别是生命周期所有者和生命周期感知者

Lifecycle定义组件状态

ViewModel创建存储流程:

组件与Livedata,Observer,Lifecycle关联流程:

 Livedata observe()

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {//已销毁组件不作处理
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//包装observer包含组件生命状态监控的LifecycleBoundObserver
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
//添加到Lifecyvle内保存
owner.getLifecycle().addObserver(wrapper);
}

LiveData 添加LifecycleBoundObserver到LifecycleRegister内处理:

public class LifecycleRegistry extends Lifecycle {

@Override
public void addObserver(LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//通过ObserverWithState包装LifecycleObserver内部进行操作管理
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
......
}
......

ObserverWithState负责分发组件状态变化,与关联的LifecycleBoundObserver状态关联

 static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver; ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
//分发组件状态到所关联Observer
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}

看一下 LifecycleBoundObserver内部代码

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner; LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
super(observer);
mOwner = owner;
}
......
//当组件周期状态变化时,处理关联的Observer
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
......
} private abstract class ObserverWrapper {
final Observer<T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION; ObserverWrapper(Observer<T> observer) {
mObserver = observer;
}
......
void activeStateChanged(boolean newActive) {//组件周期变化时判断是否需要重新分发value data
if (newActive == mActive) {//observe与组件状态一致时不处理,
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {//LiveData从非活跃到激活状态
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {//LiveData从激活到非活跃状态
onInactive();
}
if (mActive) {//组件激活状态时重新分发上一次存留数据
dispatchingValue(this);
}
}
}

LifeData分发数据处理:

setValue修改数据

@MainThread
protected void setValue(T value) {
assertMainThread("setValue");//主线程调用
mVersion++;//每次修改,版本号+1
mData = value;
dispatchingValue(null);//数据分发处理
} private void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {//分发给指定observer
considerNotify(initiator);
initiator = null;
} else {//分发Observer列表内所有注册对象
for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
} private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {//非激活状态不处理
return;
} // 是否为active状态
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}//observer dataVersion大于等于LiveData dataVersion不予处理
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//通知Observer change数据
observer.mObserver.onChanged((T) mData);
}

整体大致流程:

Android ViewModel,LiveData 简要分析的更多相关文章

  1. Android Hal层简要分析

    Android Hal层简要分析 Android Hal层(即 Hardware Abstraction Layer)是Google开发的Android系统里上层应用对底层硬件操作屏蔽的一个软件层次, ...

  2. Android初级教程通过简要分析“土司”源码,来自实现定义土司理论探讨

    由于系统自带的土司瞬间即逝,而且非常难看.因此我们就希望自定义自己的土司风格.有些实例就是基于自定义土司完成的,例如金山卫士的火箭发射,基本原理就是个土司.但是在做出自己的土司风格之前,还是要简要分析 ...

  3. Android `AsyncTask`简要分析

    AsyncTask简要分析 经典异步任务:AsyncTask,使用场景有:批量下载,批量拷贝等.官方文档就直接给出了一个批量下载的示例. private class DownloadFilesTask ...

  4. Android 5.1 Settings源代码简要分析

    转载请注明出处,谢谢~http://blog.csdn.net/u011974987/article/details/51004854. 概述: 先声明:本人工作快两年了,仍是菜鸟级别的.羞愧啊!曾经 ...

  5. 【Android】ViewModel+LiveData:更加直接地控制视图的方式

    目录 LiveData 前言 使用ViewModel+LiveData LiveData 前言   ViewModel通过将UI data保存在ViewModel类实例的内部,从而大大地将MVC中的 ...

  6. Android 4.4 Kitkat 音频实现及简要分析

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jingxia2008/article/details/26701899 在 Android 4.4 ...

  7. Activity源码简要分析总结

    Activity源码简要分析总结 摘自参考书籍,只列一下结论: 1. Activity的顶层View是DecorView,而我们在onCreate()方法中通过setContentView()设置的V ...

  8. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(34)-文章发布系统①-简要分析

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(34)-文章发布系统①-简要分析 系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET ...

  9. android recover 系统代码分析 -- 选择进入

    最近做Recovery的规范及操作指导文档,花了一些时间将流程搞清. Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级.而在进入Recover ...

  10. Appium Android Bootstrap源码分析之命令解析执行

    通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在b ...

随机推荐

  1. 记一次 .NET 某安全生产信息系统 CPU爆高分析

    一:背景 1.讲故事 今天是的第四天,头终于不巨疼了,写文章已经没什么问题,赶紧爬起来写. 这个月初有位朋友找到我,说他的程序出现了CPU爆高,让我帮忙看下怎么回事,简单分析了下有两点比较有意思. 这 ...

  2. 3、swagger调试

    Swagger: 1.将项目中所有的接口展现在页面上,这样后端程序员就不需要专门为前端使用者编写专门的接口文档: 2.当接口更新之后,只需要修改代码中的Swagger描述就可以实时生成新的接口文档了, ...

  3. Python实验报告(第7章)

    实验7:面向对象程序设计 一.实验目的和要求 1.了解面向对象的基本概念(对象.类.构造方法): 2.学会类的定义和使用: 3.掌握属性的创建和修改: 4.掌握继承的基本语法. 二.实验环境 软件版本 ...

  4. 【转载】EXCEL VBA UBound(arr,1),UBound(arr,2)解释

    Resize(UBound(arr, 1), UBound(arr, 2) 这句什么意思   resize()是一个扩展单元格地址区域的函数,有两个参数,第一个是行扩展数,第二个是列扩展数   UBo ...

  5. 过年必备!亲戚计算器「GitHub 热点速览 v.23.02」

    过完这周大家就要开始为期 7 天的春节长假了,当然有些 HG 小伙伴拥有了 10+ 天的长假就低调点不要告诉他人,以免招人妒忌.春节必经的事情可能就是走亲戚了,所以本周特推选取了一个研究亲戚关系的资深 ...

  6. mysql中的列类型

    创建数据表的时候,指定的列可以存储的数据类型: CREATE TABLE book ( bid  列类型); ① 数值类型--可以不加引号 TINYINT 微整型,占一个字节  范围-128~127 ...

  7. 记一次简单的诈骗网站Getshell

    前言:在放假期间接到一个诈骗电话.然后说京东金条利率过高让我处理下(在疫情开放期间京东客服基本上是没有人工客服),然后就慢慢的被拉入钉钉会议,然后骗子给网站的时候发现域名不对就判定成了骗子就找理由有事 ...

  8. react 高效高质量搭建后台系统 系列 —— 系统布局

    其他章节请看: react 高效高质量搭建后台系统 系列 系统布局 前面我们用脚手架搭建了项目,并实现了登录模块,登录模块所依赖的请求数据和antd(ui框架和样式)也已完成. 本篇将完成系统布局.比 ...

  9. 【分析笔记】Linux I2C-Tools 使用踩坑笔记

    一.踩坑缘由 在调试 I2C 器件时,我一般习惯于使用 i2cdetect 工具来确认芯片是否有应答,通常有应答之后,就会开始着手移植或者编写对应的驱动程序,但是在调试 sgp41 传感器时却不灵了. ...

  10. JSP第七次作业

    1.做一个图书类Book id,name,price ,get,set访问器,构造方法2个,1个无参,1个有参做一个测试类,在main中创建3个图书对象,放到list集合中.做一个菜单,可以添加,删除 ...