写点什么

Android Virtualview:淘宝、天猫 又一个动态化,android 界面开发基础

用户头像
Android架构
关注
发布于: 37 分钟前

<?xml version="1.0" encoding="utf-8"?><VHLayoutflag="flag_exposure|flag_clickable"orientation="H"layoutWidth="match_parent"layoutHeight="wrap_content"><NImageid="1"src="{title}"layoutGravity="v_center"gravity="{style.font-size}"textColor="${style.color}"layoutWidth="match_parent"layoutHeight="wrap_content"/></VHLayout>


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



使用说明见文章[virtualview_tools 使用指南](


)


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


2.2.2 二进制文件描述

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


2.2.2 编译流程

  • 一个业务组件对应着一份 XML 模板 = 单独编译成二进制数据


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


  • 编译规则 编译时,模板里涉及的资源包括颜色值、各种枚举、基础组件的类型等都会被序列化映射成整数;不能序列化成整数的资源如字符串,就分配一个索引 Id 指向它 & 将它们单独存储到一块区域里


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

  2. 序列化的规则如下:



  • 编译流程


2.3 模板数据 下发到客户端

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


获取有 2 种路径:


  1. 直接将编译后的模板打包到客户端里,开发者通过代码加载

  2. 框架先发布到模板管理后台,客户端在线更新到模板数据(即实现了动态更新)



流程 3:客户端加载界面

  • 客户端获取到编译后的界面模板后,进行加载 & 解析,最终渲染出视图界面

  • 步骤流程如下图


3.1 解析模板数据

  • 具体描述 客户端获得编译后的模板数据(二进制数据)后,立即 进行解析


  1. 如校验版本号,合法性,读取头信息等

  2. 客户端渲染组件 从解析 编译后的模板数据开始


  • 流程解析 解析过程 = 二进制编译的逆过程


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


3.2 加载组件视图

  • 具体描述 当用户传入一个模板名称,框架内部就会根据名称去之前解析 XML 界面模板的数据里找到 与此名称匹配的模板数据,然后加载 & 创建出真正的组件

  • 流程解析


3.3 绑定业务数据

  • 具体描述 开发者在组件属性里可通过 表达式 指定使用哪个数据字段,即将业务数据绑定到组件上


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


  • 流程解析 在创建组件的过程中,当解析属性碰到表达式时,会将该属性的 key、表达式值、所属的基础组件等关系存储起来,等真实数据到达后再通过 表达式里的定义 访问数据 & 将真实值设置给组件的属性,即将真实的数据绑定到基础组件的属性上


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

  2. 此处接收的数据是 JSON 格式


4.3 总结



5. 整体架构设计

  • 根据上述方案 & 工作流程,VirtualView的整体框架分为 2 部分:核心功能模块(5 个模块) + 配套工具 & 服务。具体如下:



  • 下面,我将对每部分进行详细分析

模块 1:加载模块

  • 示意图



  • 说明


模块 2:构造模块

  • 示意图



  • 说明



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

a. 基础组件模型

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


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


模块 3:辅助模块

  • 示意图



  • 说明


![示意图](https://user-gold-cdn.xitu.io/2018/2/24/161c547f2cff9dec?imageView2/0


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


/w/1280/h/960/ignore-error/1)


  • 特别注意:引入用户数据绑定的表达式的原因 开发业务组件时,基础属性 / 样式不能在模板里直接写死,而是需从数据里动态获取


/**


  • 访问数据属性的表达式

  • 语法说明

  • 示例如下*/


{data[0].benefitImgUrl};


/**


  • 条件表达式

  • 作用:根据数据中某个字段 来设置值的属性

  • 语法说明

  • 示例如下*/@{${logoUrl} ? visible : invisible };

模块 4:管理模块

  • 示意图



  • 说明


模块 5:更新模块

  • 示意图



  • 说明


配套使用的工具 & 服务

  • 示意图



  • 说明


总结



6. 使用教程

  • 根据上述工作流程,其使用流程同样分为 3 步:创建UI组件、创建界面模板 & 客户端加载界面

  • 下面,我将根据上述 3 个步骤进行详细解析

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"?><VHLayoutflag="flag_exposure|flag_clickable"orientation="V"layoutWidth="match_parent"layoutHeight="wrap_content"><VHLayoutflag="flag_exposure|flag_clickable"orientation="H"layoutWidth="match_parent"layoutHeight="wrap_content"><NImageid="1"src="{title}"layoutGravity="v_center"gravity="{style.font-size}"textColor="{logoUrl}"layoutMarginLeft="8"layoutMarginRight="8"layoutMarginTop="8"layoutMarginBottom="8"layoutWidth="32"layoutHeight="32"/><VTextid="2"text="{style.text-align}"textSize="{style.color}"layoutWidth="match_parent"layoutHeight="wrap_content"/></VHLayout></VHLayout>


  • 属性数据来源: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"}

6.2.2 编译成二进制数据

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



使用说明见文章[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() {


@Overridepublic boolean process(EventData data) {//handle herereturn true;}});vafContext.getEventManager().register(EventManager.TYPE_Exposure, new IEventProcessor() {

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android Virtualview:淘宝、天猫 又一个动态化,android界面开发基础