其他分享
首页 > 其他分享> > Android Virtualview:淘宝、天猫 又一个动态化、高性能的UI框架力作

Android Virtualview:淘宝、天猫 又一个动态化、高性能的UI框架力作

作者:互联网

注: a. 自定义组件应继承基础组件 b. 系统封装UI组件的原理 同 “自定义UI组件,下面将具体讲解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V4cCTqWc-1636696685966)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e622e4a99?imageView2/0/w/1280/h/960/ignore-error/1)]

###1.2 自定义UI组件 若框架内置的UI组件无法满足需求,则开发者可自定义UI组件

即 上述则是虚拟化创建组件的过程

  1. 实现基础组件需遵循一个接口的规范:定义了渲染过程中所需的3个流程:测量尺寸阶段、布局阶段 & 绘制阶段

a. 定义这3个阶段是为了符合Android系统的使用,即View绘制的三大流程:measure过程、layout过程、draw过程。若不了解,请看文章 (2)自定义View Measure过程 - 最易懂的自定义View原理系列 (3)自定义View Layout过程 - 最易懂的自定义View原理系列 (4)自定义View Draw过程- 最易懂的自定义View原理系列 b. 在 iOS 平台下也需按照本方案的规范去处理

  1. 这3个过程具体如下:(与Android View绘制的三大流程相似)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pRzG7qSJ-1636696686017)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e62883774?imageView2/0/w/1280/h/960/ignore-error/1)]

不论是虚拟 / 原生组件,都采用上述模型 & 流程定义 a. 对于虚拟组件:在这些接口里实现相关逻辑 / 通过封装原生组件实现 b. 对于原生组件:在这些接口的实现里 调用原生组件的对应逻辑 结论:可混合使用虚拟控件 & 实体控件

至此,对于宿主的布局容器来说,包装在内部的组件不分虚拟化 / 原生,暴露在外的接口相同,只要将宿主容器像普通的 View 一样添加到的视图界面上,就可在后续的渲染过程中显示出来。

如下所示的组件: a. 普通的原生开发:2层(宿主容器层 + 图片组件层) b. 虚拟化开发:采用虚拟化开发后,最终呈现的 View层级只有一个宿主容器(实际上,图片组件被绘制在Canvas里了)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vctL40A9-1636696686018)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e667aec4e?imageView2/0/w/1280/h/960/ignore-error/1)]

1.3 总结

创建UI组件有2种方式:

  1. 直接使用框架内置的UI组件
  2. 自定义组件:通过封装好的Canvas流程,按照指定接口协议实现绘制逻辑 / 封装原生组件

流程2:创建界面模板 & 下发

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kxPPF8y7-1636696686019)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e781f2e75?imageView2/0/w/1280/h/960/ignore-error/1)]

2.1 创建XML界面模板

注:需使用专门的工具virtualview_tools编写,其 使用说明见文章virtualview_tools使用指南

  1. 脱离了平台限制,即一套模板可同时在AndroidiOS上使用
  2. 运行时动态加载 XML 模板数据,动态更新界面结构

// 引用的组件通过流程1中获取
// 动态数据通过表达式从 JSON 数据里获取

<?xml version="1.0" encoding="utf-8"?>




// 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”
}

2.2 编译成二进制数据

2.2.1 具体描述

使用专门的工具virtualview_tools将编写好的XML界面模板编译成二进制数据,编译后的文件的后缀名是.out

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FbWbvt7d-1636696686020)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e77440d0f?imageView2/0/w/1280/h/960/ignore-error/1)]

使用说明见文章virtualview_tools使用指南

注:为什么通过 XML 编写的业务组件 不直接在客户端里运行使用,而是先进行一次二进制序列化操作?

![示意图](https://user-gold-cdn.

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

浏览器打开:qq.cn.hn/FTe 免费领取

xitu.io/2018/2/24/161c547e85ac1b64?imageView2/0/w/1280/h/960/ignore-error/1)

2.2.2 二进制文件描述

借鉴了 Android 系统编译模板文件的思路,格式 & 描述具体如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-noSXIs35-1636696686021)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e8816f883?imageView2/0/w/1280/h/960/ignore-error/1)]

2.2.2 编译流程

编译数据 含除内置字符串资源外 它依赖的所有字符串、表达式资源

  1. 原因:当模板在线发布、字符串有变动的情况下,能够不影响原来的字符串资源索引;否则若按照带有顺序约定的协议来分配资源索引,很容易在模板变更时 同一索引值在变更前后指向的资源内容是不一样,影响稳定性和动态性
  2. 序列化的规则如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZoU95NLg-1636696686022)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e8f61d85a?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vqsksxOt-1636696686023)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e9b28e415?imageView2/0/w/1280/h/960/ignore-error/1)]

2.3 模板数据 下发到客户端

即 客户端获取编译后的二进制数据

获取有2种路径:

  1. 直接将编译后的模板打包到客户端里,开发者通过代码加载
  2. 框架先发布到模板管理后台,客户端在线更新到模板数据(即实现了动态更新)

流程3:客户端加载界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xv0sOkZu-1636696686024)(https://user-gold-cdn.xitu.io/2018/2/24/161c547eb1e0f7a9?imageView2/0/w/1280/h/960/ignore-error/1)]

3.1 解析模板数据

  1. 如校验版本号,合法性,读取头信息等
  2. 客户端渲染组件 从解析 编译后的模板数据开始

但解析流程只负责提取原始数据 & 组织格式,并无构建出组件对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nnY4YbOE-1636696686024)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e9e35786f?imageView2/0/w/1280/h/960/ignore-error/1)]

3.2 加载组件视图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFb1rt32-1636696686025)(https://user-gold-cdn.xitu.io/2018/2/24/161c547eb4f0b63f?imageView2/0/w/1280/h/960/ignore-error/1)]

3.3 绑定业务数据

因业务数据是动态的,故从模板创建的组件不含业务数据

  1. 通过表达式解析、访问得到的属性值,会缓存起来,当原始数据引用不变时,每次访问都会获取到缓存值
  2. 此处接收的数据是 JSON 格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bJ12jVDb-1636696686025)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ebe073f01?imageView2/0/w/1280/h/960/ignore-error/1)]

4.3 总结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AdNC2BO3-1636696686026)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ec5c9849a?imageView2/0/w/1280/h/960/ignore-error/1)]


5. 整体架构设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jYRlpB47-1636696686026)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ec7d29af3?imageView2/0/w/1280/h/960/ignore-error/1)]

模块1:加载模块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DxmRxcz3-1636696686027)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ee3701f85?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D3UTwXwh-1636696686027)(https://user-gold-cdn.xitu.io/2018/2/24/161c547eec506745?imageView2/0/w/1280/h/960/ignore-error/1)]

模块2:构造模块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-poQiGJjA-1636696686028)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ef5002df5?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zU45pSNP-1636696686028)(https://user-gold-cdn.xitu.io/2018/2/24/161c547ef596cca8?imageView2/0/w/1280/h/960/ignore-error/1)]

此处详细分析 基础组件模型 & 虚拟组件

a. 基础组件模型

含基础组件 & 基础属性,具体如下

注:自定义的基础组件应继承基础定义 & 扩展

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xqpjDTYu-1636696686029)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e622e4a99?imageView2/0/w/1280/h/960/ignore-error/1)]

模块3:辅助模块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UikvqLp3-1636696686029)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f1f689914?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rth0QqJt-1636696686030)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f2cff9dec?imageView2/0/w/1280/h/960/ignore-error/1)]

/**

${benefitImgUrl};
${data[0].benefitImgUrl};

/**

模块4:管理模块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HPXaUYci-1636696686030)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f2defb2a6?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eJN4k8LB-1636696686031)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f4cfec89e?imageView2/0/w/1280/h/960/ignore-error/1)]

模块5:更新模块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbNRAdcg-1636696686031)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f4cee88da?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3N0aBaGI-1636696686032)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f53e2701b?imageView2/0/w/1280/h/960/ignore-error/1)]

配套使用的工具 & 服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5XHkjT8-1636696686032)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f5726ecbe?imageView2/0/w/1280/h/960/ignore-error/1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YSz1frDc-1636696686032)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f7852fa97?imageView2/0/w/1280/h/960/ignore-error/1)]

总结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cGTJGmd3-1636696686034)(https://user-gold-cdn.xitu.io/2018/2/24/161c547f7e1f7623?imageView2/0/w/1280/h/960/ignore-error/1)]


6. 使用教程

6.1 创建UI组件

从一文可知,创建UI组件有2种方式:

  1. 直接使用框架内置的UI组件
  2. 自定义组件:通过封装好的Canvas流程,按照指定接口协议实现绘制逻辑 / 封装原生组件

此处为方便讲解,直接使用框架内置的UI组件

6.2 创建界面模板

此步骤包括:创建XML界面模板、编译成二进制数据、模板下发

6.2.1 创建XML界面模板

根据业务需求,使用XML编写模板

注:需使用专门的工具virtualview_tools编写,其 使用说明见文章virtualview_tools使用指南

/**

*/

<?xml version="1.0" encoding="utf-8"?>










{
“style”: {
“text-align”: “h_center”,
“font-size”: “20”,
“color”: “#FF5000”
},
“title”: “超高性 99.9% 的用户觉得很快”,
“logoUrl”: “https://gw.alicdn.com/tfs/TB1yGIdkb_I8KJjy1XaXXbsxpXa-72-72.png”
}

6.2.2 编译成二进制数据

使用专门的工具virtualview_tools将编写好的XML界面模板编译成二进制数据,编译后的文件的后缀名是.out

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QRO5Xffm-1636696686034)(https://user-gold-cdn.xitu.io/2018/2/24/161c547e77440d0f?imageView2/0/w/1280/h/960/ignore-error/1)]

使用说明见文章virtualview_tools使用指南

6.2.3 模板下发到客户端

有2种路径:

  1. 直接将编译后的模板打包到客户端里,开发者通过代码加载
  2. 框架先发布到模板管理后台,客户端在线更新到模板数据(即实现了动态更新)

此处选择方式1

6.3 客户端解析 & 加载界面模板

具体使用如下

// 1. 初始化图片加载器
VafContext.loadImageLoader(mContext.getApplicationContext());

// 2. 初始化 ViewManager 对象
ViewManager viewManager = vafContext.getViewManager();
viewManager.init(mContext.getApplicationContext());

// 3. 加载编译后的模板数据(二进制文件)
// 方式1:直接加载二进制字节数组(推荐使用)
viewManager.loadBinBufferSync(TMALLCOMPONENT1.BIN);
viewManager.loadBinBufferSync(TMALLCOMPONENT2.BIN);
// 方式2:通过二进制文件路径加载
viewManager.loadBinFileSync(TMALLCOMPONENT1_PATH);
viewManager.loadBinFileSync(TMALLCOMPONENT2_PATH);

// 4. 注册事件处理器,如常用的点击、曝光处理
vafContext.getEventManager().register(EventManager.TYPE_Click, new IEventProcessor() {

@Override
public boolean process(EventData data) {
//handle here
return true;
}
});
vafContext.getEventManager().register(EventManager.TYPE_Exposure, new IEventProcessor() {

@Override
public boolean process(EventData data) {
//handle here
方式2:通过二进制文件路径加载
viewManager.loadBinFileSync(TMALLCOMPONENT1_PATH);
viewManager.loadBinFileSync(TMALLCOMPONENT2_PATH);

// 4. 注册事件处理器,如常用的点击、曝光处理
vafContext.getEventManager().register(EventManager.TYPE_Click, new IEventProcessor() {

@Override
public boolean process(EventData data) {
//handle here
return true;
}
});
vafContext.getEventManager().register(EventManager.TYPE_Exposure, new IEventProcessor() {

@Override
public boolean process(EventData data) {
//handle here

标签:imageView2,Virtualview,天猫,动态化,防盗链,https,组件,模板,图片
来源: https://blog.csdn.net/m0_63737792/article/details/121286764