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

// 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:辅助模块

  • 示意图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 说明

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

/**

  • 访问数据属性的表达式
  • 语法说明
  •   a. 以 “${” 开头、以 “}” 结束
    
  •   b. 对于Map,通过“.”操作符访问
    
  •   c. 对于 Array  /  List,通过 “[]” 操作符访问
    
  • 示例如下
    */

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

/**

  • 条件表达式
  • 作用:根据数据中某个字段 来设置值的属性
  • 语法说明
  •   a. 以 “@{” 开头、以 “}” 结束,
    
  •   b. 中间部分 = 表达式的具体内容:  条件表达式 ? 结果表达式[1] : 结果表达式[2]
    
  •       注:1. 当条件表达式成立的时,使用结果表达式[1],否则使用结果表达式[2]
    
  •          2. 条件表达式支持布尔类型、字符串类型、JSONObject、JSONArray
    
  •   c. 对于 Array  /  List,通过 “[]” 操作符访问
    
  • 示例如下
    */
    @{${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使用指南

  • 示例布局

/**

  • 使用说明:
  • 1. 控件引用:通过XML引用控件为方便讲解,XML内引用的VHLayout、NImage、NText 都是框架内置的控件:2个横向线性布局;每个布局 = 1个图 + 1个文本
    
  • 2. 属性设置:可写死 / 通过表达式绑定一个数据字段(JSON)引用
    
  • 布局说明:
  • 1. 引用的控件VHLayout、NImage、NText等都是框架内置的控件
    
  • 2. 整个布局 = 2个横向线性布局,每个布局 = 1个图 + 1个文本
    

*/

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

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() {

@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
return true;
}
});

// 5. 通过组件名参数 name 生成组件实例
View container = vafContext.getContainerService().getContainer(name, true);
mLinearLayout.addView(container);

// 6. 为组件绑定真实的数据
// 假若您在组件模板里写了数据绑定的表达式
IContainer iContainer = (IContainer)container;
JSONObject json = getJSONDataFromAsset(data);
if (json != null) {
iContainer.getVirtualView().setVData(json);
}

  • 测试结果

下图展示的“超高性 99.9% 的用户觉得很快”即为VirtualView的展示效果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

至此,关于VirtualView的使用讲解完毕

更加详细使用,请参考文章VirtualView的使用文档
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

文末

初级工程师拿到需求会直接开始做,然后做着做着发现有问题了,要么技术实现不了,要么逻辑有问题。

而高级工程师拿到需求会考虑很多,技术的可行性?对现有业务有没有帮助?对现有技术架构的影响?扩展性如何?等等…之后才会再进行设计编码阶段。

而现在随着跨平台开发,混合式开发,前端开发之类的热门,Android开发者需要学习和掌握的技术也在不断的增加。

通过和一些行业里的朋友交流讨论,以及参考现在大厂面试的要求。我们花了差不多一个月时间整理出了这份Android高级工程师需要掌握的所有知识体系。你可以看下掌握了多少。

混合式开发,微信小程序。都是得学会并且熟练的

这些是Android相关技术的内核,还有Java进阶

高级进阶必备的一些技术。像移动开发架构项目实战等

Android前沿技术;包括了组件化,热升级和热修复,以及各种架构跟框架的详细技术体系

以上即是我们整理的Android高级工程师需要掌握的技术体系了。可能很多朋友觉得很多技术自己都会了,只是一些新的技术不清楚而已。应该没什么太大的问题。

而这恰恰是问题所在!为什么别人高级工程师能年限突破30万,而你只有十几万呢?

就因为你只需补充你自己认为需要的,但并不知道企业需要的。这个就特别容易造成差距。因为你的技术体系并不系统,是零碎的,散乱的。那么你凭什么突破30万年薪呢?

我这些话比较直接,可能会戳到一些人的玻璃心,但是我知道肯定会对一些人起到点醒的效果的。而但凡只要有人因为我的这份高级系统大纲以及这些话找到了方向,并且付出行动去提升自我,为了成功变得更加努力。那么我做的这些就都有了意义。

喜欢的话请帮忙转发点赞一下能让更多有需要的人看到吧。谢谢!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

dAt5DGL-1711542656411)]

以上即是我们整理的Android高级工程师需要掌握的技术体系了。可能很多朋友觉得很多技术自己都会了,只是一些新的技术不清楚而已。应该没什么太大的问题。

而这恰恰是问题所在!为什么别人高级工程师能年限突破30万,而你只有十几万呢?

就因为你只需补充你自己认为需要的,但并不知道企业需要的。这个就特别容易造成差距。因为你的技术体系并不系统,是零碎的,散乱的。那么你凭什么突破30万年薪呢?

我这些话比较直接,可能会戳到一些人的玻璃心,但是我知道肯定会对一些人起到点醒的效果的。而但凡只要有人因为我的这份高级系统大纲以及这些话找到了方向,并且付出行动去提升自我,为了成功变得更加努力。那么我做的这些就都有了意义。

喜欢的话请帮忙转发点赞一下能让更多有需要的人看到吧。谢谢!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值