一、什么是Weex?
官方的解释是:一个可以使用现代化的Web技术开发高性能原生应用的框架。具体来说就是用一套代码来构建Android、iOS和Web应用,使用JavaScript语言和前端开发经验来开发移动应用。赋予客户端界面动态化能力的同时,使用原生渲染,与纯H5页面相比体验更佳,与之相类似的有React Native。
二、为什么选择Weex
没有最好的框架,只有最适合的框架,正确的技术选型可以提高生产力,达到事半功倍的效果。Weex支持Vue.js和Rax,支持跨平台、热更新,作为一个UI框架相对轻量,上手难度不高并且团队有现成的技术栈,综合考虑公司选择了Weex进行跨平台开发。
三、Weex整体结构
先放一张官方的Weex架构图:
framework就以Vue.js为例,Weex的大致流程是这样的:
- 前端开发用Vue开发功能,完成后代码通过webpack打包编译生成jsbundle
- 将jsbundle部署到服务器上
- 客户端打开一个weex页面,通过网络下载jsbundle,客户端会通过JS执行引擎JSCore(ios)/V8(android)执行该jsbundle
- JS执行引擎执行jsbundle,解析为一个个渲染指令并调用WXBridge与Native进行通信
- WXBridge将指令分发给native渲染引擎,最终由native完成页面的渲染
从这里不难看出,jsbundle提供了动态化能力,解决了客户端频繁发版的问题,而视图仍然交给原生绘制,使用原生的控件和API,保证了UI的还原度,性能相比纯WebView渲染的方式也得到了提升。
四、Weex SDK
Weex融合了客户端的性能优势和Web的动态化能力,而赋予这一切的就是其提供的一整套框架,这其中最核心的部分就是Native与JS引擎的交互能力,Weex SDK也是以此为基础搭建形成的。
整体架构
通信层
- WXBridge:通信的桥梁,Android和JS之间互相调用的接口都在此类中实现
- WXBridgeManager:JS Bridge的管理者,JS调用WXBridge的代码后都是交给Manager完成的
框架层
- WXRenderManager: 统一管理对Native View的各种操作
- WXModuleManager: 提供对Weex模块的管理,包括全局模块(单例)和实例模块(多次创建)
- WXSDKManager: 内容提供者,WXBridgeManager、WXRenderManager都可以通过该类获取
- WXSDKEngine: 非常重要,Weex运转起来的入口,包括初始化设置config、获取宿主app的上下文、component的注册、module的注册等
组件层
- WXComponent: 最常用的就是UI组件,通过原生预先注册的方式扩展组件提供给前端同学调用
- WXModule: 和WXComponent类似对Activity的生命周期做了hook,主要用途是扩展非UI的特点功能,比如提供hybrid能力
五、初始化
使用Weex,免不了要在客户端本地做一些接入及配置的工作。Weex提供了一套清晰直观的API供开发者进行必要的初始化,以及根据自己的实际需要进行扩展。
集成
关于Weex如何集成到Android应用,官网有基本示例:
weex.apache.org/zh/guide/de…
基于官方提供的weex-cli,我们可以自己实现一个Demo帮助理解前端代码如何转换为Native视图:
Demo很简单,一个TextView,点击事件弹了个toast。写法上也基本是标准的Vue结构,经过webpack打包后index.vue变成了index.js:
该js文件也就是我们常说的JSBundle,最后客户端拉取都是拿的这个解析的。这样一个简单的示例,背后却涉及了Module、Component、渲染、事件等,Weex SDK对此做了相当多的工作。
初始化
一般我们会将Weex的初始化及一些自定义配置和扩展放到应用初始化的时候
InitConfig config = new InitConfig.Builder()
.setImgAdapter(new ImageAdapter())
.setHttpAdapter(new DefaultWXHttpAdapter())
.setWebSocketAdapterFactory(new WebSocketAdapterFactory()
.build();
WXSDKEngine.initialize(applicationContext, config);
IniConfig内部使用建造者模式,对外提供了很多自定义配置。然后调用WXSDKEngine的初始化方法,这里面主要的任务都由doInitInternal完成
private static void doInitInternal(final Application application, final InitConfig config) {
WXEnvironment.sApplication = application;
WXEnvironment.JsFrameworkInit = false;
WXBridgeManager.getInstance().postWithName(new Runnable() {
public void run() {
//加载weex需要的so库
}
}, (WXSDKInstance)null, "doInitWeexSdkInternal");
register();
}
首先将applicationContext传入,保存到WXEnvironment作为全局唯一变量,后面很多地方都要使用到应用的上下文。接着就是Weex预先注册的一些内置组件:
//注册Native组件
registerComponent((IFComponentHolder)(new SimpleComponentHolder(WXText.class, new Creator())), false, "text");
...
registerComponent("indicator", WXIndicator.class, true);
...
//注册非UI功能模块
registerModule("stream", WXStreamModule.class);
...
同时Weex会保存屏幕尺寸、状态栏高度等相关系统属性,方便后续UI适配。这些工作完成之后App就拥有了最基本的Weex能力,通过WXSDKInstance完成页面渲染的相关工作并展现到屏幕上。同时Weex也提供了扩展能力,需要客户端同学根据自己的需要去完成,这些扩展组件也需要进行初始化。
六、总结
上面简单介绍了Weex的大致流程和初始化方法,实际上Weex提供的能力不仅限于UI展示,还包括:
- 数据存储
- 网络通信
- 设备硬件功能调用
- 手势交互操作
- 其他扩展能力
当然这些能力都需要客户端支持,而这一整套都是基于Weex SDK实现的,后面会详细介绍Weex的工作原理和相关问题,基于官方目前的稳定版本0.28.0 github.com/apache/incu…