[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BhuAMnIh-1636293637117)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e362d4a05?imageView2/0/w/1280/h/960/ignore-error/1)]
根据Tangram v1.0
中 出现的问题:UI
组件无法动态更新 & 加载性能低,VirtualView
的具体解决方案如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U8UPf22q-1636293637157)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e38d9afa3?imageView2/0/w/1280/h/960/ignore-error/1)]
VirtualView
的实现方案是:虚拟化开发[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YNuxmpBD-1636293637158)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e3a9e3fb1?imageView2/0/w/1280/h/960/ignore-error/1)]
之所以称为虚拟化,是因为
Canvas
绘制的视图不存在一一对应的实体View
从上可知,VirtualView
的创新在于:
XML
模板实现组件的动态性Canvas
)开发组件,提升了组件的渲染性能VirtualView
的本质原理 & 整体架构后VirtualView
的工作流程VirtualView
的工作流程分为3大部分:创建UI组件、创建界面模板 & 客户端加载界面[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ww9LlCKH-1636293637159)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e3a790a91?imageView2/0/w/1280/h/960/ignore-error/1)]
下面我将对每个流程的原理 & 过程详细分析
UI
组件[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ijZ3n4t-1636293637160)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e3c3ba078?imageView2/0/w/1280/h/960/ignore-error/1)]
有2种创建方式:使用框架内置(封装好)的UI
组件 / 自定义
UI
组件UI
组件而不需自身创建注: a. 自定义组件应继承基础组件 b. 系统封装
UI
组件的原理 同 “自定义UI
组件,下面将具体讲解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HSgrIFyG-1636293637161)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e622e4a99?imageView2/0/w/1280/h/960/ignore-error/1)]
###1.2 自定义UI组件 若框架内置的UI
组件无法满足需求,则开发者可自定义UI
组件
VirtualView
抽象 & 封装了 Canvas
绘制视图的流程,使得开发者只需按指定的接口协议实现1个组件的绘制逻辑:测量、绘制 & 绘制,即能实现在宿主容器通过 Canvas
直接绘制 UI
内容,从而创建虚拟化组件即 上述则是虚拟化创建组件的过程
a. 定义这3个阶段是为了符合
Android
系统的使用,即View
绘制的三大流程:measure
过程、layout
过程、draw
过程。若不了解,请看文章 (2)自定义View Measure过程 - 最易懂的自定义View原理系列 (3)自定义View Layout过程 - 最易懂的自定义View原理系列 (4)自定义View Draw过程- 最易懂的自定义View原理系列 b. 在iOS
平台下也需按照本方案的规范去处理
Android View
绘制的三大流程相似)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iaSySCRz-1636293637161)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e62883774?imageView2/0/w/1280/h/960/ignore-error/1)]
不论是虚拟 / 原生组件,都采用上述模型 & 流程定义 a. 对于虚拟组件:在这些接口里实现相关逻辑 / 通过封装原生组件实现 b. 对于原生组件:在这些接口的实现里 调用原生组件的对应逻辑 结论:可混合使用虚拟控件 & 实体控件
至此,对于宿主的布局容器来说,包装在内部的组件不分虚拟化 / 原生,暴露在外的接口相同,只要将宿主容器像普通的 View
一样添加到的视图界面上,就可在后续的渲染过程中显示出来。
View
个数就越少,即层级越扁平如下所示的组件: a. 普通的原生开发:2层(宿主容器层 + 图片组件层) b. 虚拟化开发:采用虚拟化开发后,最终呈现的 View层级只有一个宿主容器(实际上,图片组件被绘制在
Canvas
里了)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8uQAdEif-1636293637162)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e667aec4e?imageView2/0/w/1280/h/960/ignore-error/1)]
创建UI
组件有2种方式:
UI
组件Canvas
流程,按照指定接口协议实现绘制逻辑 / 封装原生组件XML
界面模板、编译成二进制数据、下发等[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0vZPzLK-1636293637163)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e781f2e75?imageView2/0/w/1280/h/960/ignore-error/1)]
注:需使用专门的工具
virtualview_tools
编写,其 使用说明见文章virtualview_tools使用指南
Android
平台上通过 XML
搭建界面的方式Android
、iOS
上使用XML
模板数据,动态更新界面结构// 引用的组件通过流程1中获取
// 动态数据通过表达式从 JSON 数据里获取
// JSON数据
{
“style”: {
“text-align”: “h_center”,
“font-size”: “20”,
“color”: “#FF5000”
},
“title”: “超高性 99.9% 的用户觉得很快”,
“logoUrl”: “https://gw.alicdn.com/tfs/TB1yGIdkb_I8KJjy1XaXXbsxpXa-72-72.png”
}
使用专门的工具virtualview_tools
将编写好的XML
界面模板编译成二进制数据,编译后的文件的后缀名是.out
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KM5O3zFl-1636293637163)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e77440d0f?imageView2/0/w/1280/h/960/ignore-error/1)]
使用说明见文章virtualview_tools使用指南
注:为什么通过 XML 编写的业务组件 不直接在客户端里运行使用,而是先进行一次二进制序列化操作?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dDcbmJTW-1636293637164)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e85ac1b64?imageView2/0/w/1280/h/960/ignore-error/1)]
借鉴了 Android
系统编译模板文件的思路,格式 & 描述具体如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-huvJiNRW-1636293637165)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e8816f883?imageView2/0/w/1280/h/960/ignore-error/1)]
XML
模板 = 单独编译成二进制数据编译数据 含除内置字符串资源外 它依赖的所有字符串、表达式资源
Id
指向它 & 将它们单独存储到一块区域里
- 原因:当模板在线发布、字符串有变动的情况下,能够不影响原来的字符串资源索引;否则若按照带有顺序约定的协议来分配资源索引,很容易在模板变更时 同一索引值在变更前后指向的资源内容是不一样,影响稳定性和动态性
- 序列化的规则如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1kgjMR54-1636293637165)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e8f61d85a?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jR5kbtkc-1636293637166)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e9b28e415?imageView2/0/w/1280/h/960/ignore-error/1)]
即 客户端获取编译后的二进制数据
获取有2种路径:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZFA1WD1v-1636293637166)(https://user-gold-cdn.xitu.io/2018/2/24/161c547eb1e0f7a9?imageView2/0/w/1280/h/960/ignore-error/1)]
- 如校验版本号,合法性,读取头信息等
- 客户端渲染组件 从解析 编译后的模板数据开始
但解析流程只负责提取原始数据 & 组织格式,并无构建出组件对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YSYaakG7-1636293637167)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e9e35786f?imageView2/0/w/1280/h/960/ignore-error/1)]
具体描述 当用户传入一个模板名称,框架内部就会根据名称去之前解析XML界面模板的数据里找到 与此名称匹配的模板数据,然后加载 & 创建出真正的组件
流程解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHOp8gxU-1636293637167)(https://user-gold-cdn.xitu.io/2018/2/24/161c547eb4f0b63f?imageView2/0/w/1280/h/960/ignore-error/1)]
因业务数据是动态的,故从模板创建的组件不含业务数据
- 通过表达式解析、访问得到的属性值,会缓存起来,当原始数据引用不变时,每次访问都会获取到缓存值
- 此处接收的数据是
JSON
格式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xVrYBheD-1636293637168)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ebe073f01?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XaauJPJ0-1636293637168)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ec5c9849a?imageView2/0/w/1280/h/960/ignore-error/1)]
VirtualView
的整体框架分为2部分:核心功能模块(5个模块) + 配套工具 & 服务。具体如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-voCHWzph-1636293637168)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ec7d29af3?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aFoExRnY-1636293637169)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ee3701f85?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NwM9XPk5-1636293637169)(https://user-gold-cdn.xitu.io/2018/2/24/161c547eec506745?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kpgAvpyi-1636293637170)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ef5002df5?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e2PHCAJg-1636293637170)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ef596cca8?imageView2/0/w/1280/h/960/ignore-error/1)]
此处详细分析 基础组件模型 & 虚拟组件
含基础组件 & 基础属性,具体如下
注:自定义的基础组件应继承基础定义 & 扩展
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gtzsty22-1636293637171)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e622e4a99?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfktgFw9-1636293637171)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f1f689914?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F59ODEJS-1636293637172)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f2cff9dec?imageView2/0/w/1280/h/960/ignore-error/1)]
/**
a. 以 “${” 开头、以 “}” 结束
b. 对于Map,通过“.”操作符访问
c. 对于 Array / List,通过 “[]” 操作符访问
${benefitImgUrl};
${data[0].benefitImgUrl};
/**
a. 以 “@{” 开头、以 “}” 结束,
b. 中间部分 = 表达式的具体内容: 条件表达式 ? 结果表达式[1] : 结果表达式[2]
注:1. 当条件表达式成立的时,使用结果表达式[1],否则使用结果表达式[2]
2. 条件表达式支持布尔类型、字符串类型、JSONObject、JSONArray
c. 对于 Array / List,通过 “[]” 操作符访问
![示意图](https://user-gold-cdn.xitu.io/2018/2/2
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
4/161c547f2defb2a6?imageView2/0/w/1280/h/960/ignore-error/1)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HmugEM2g-1636293637172)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f4cfec89e?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B6zWXe1B-1636293637172)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f4cee88da?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BrXSF68K-1636293637173)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f53e2701b?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WwPFuEbw-1636293637173)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f5726ecbe?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2sbnNmy-1636293637174)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f7852fa97?imageView2/0/w/1280/h/960/ignore-error/1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E8mjiXTD-1636293637174)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f7e1f7623?imageView2/0/w/1280/h/960/ignore-error/1)]
UI
组件、创建界面模板 & 客户端加载界面从一文可知,创建UI
组件有2种方式:
UI
组件Canvas
流程,按照指定接口协议实现绘制逻辑 / 封装原生组件此处为方便讲解,直接使用框架内置的UI
组件
此步骤包括:创建XML界面模板、编译成二进制数据、模板下发
根据业务需求,使用XML编写模板
注:需使用专门的工具
virtualview_tools
编写,其 使用说明见文章virtualview_tools使用指南
/**
1. 控件引用:通过XML引用控件为方便讲解,XML内引用的VHLayout、NImage、NText 都是框架内置的控件:2个横向线性布局;每个布局 = 1个图 + 1个文本
从一文可知,创建UI
组件有2种方式:
UI
组件Canvas
流程,按照指定接口协议实现绘制逻辑 / 封装原生组件此处为方便讲解,直接使用框架内置的UI
组件
此步骤包括:创建XML界面模板、编译成二进制数据、模板下发
根据业务需求,使用XML编写模板
注:需使用专门的工具
virtualview_tools
编写,其 使用说明见文章virtualview_tools使用指南
/**
1. 控件引用:通过XML引用控件为方便讲解,XML内引用的VHLayout、NImage、NText 都是框架内置的控件:2个横向线性布局;每个布局 = 1个图 + 1个文本