[关闭]
@qinyun 2018-06-07T11:31:39.000000Z 字数 4519 阅读 2008

Weex技术在苏宁移动办公开发中的实践

未分类


一、 什么是weex

Weex是一套简单易用的跨平台开发方案,能以web的开发体验构建高性能、可扩展的native应用,为了做到这些,Weex与 Vue合作,使用 Vue 作为上层框架,并遵循 W3C 标准实现了统一的 JSEngine 和 DOM API,打造三端一致的 native 应用。其架构如下所示:

将weex工程文件编译成JS bundle,发布到云端,由客户端下载后,通过浏览器里的 JavaScript 引擎或 Weex SDK 运行起来的。

为了能掌握weex编程技术,开发人员需要熟悉以下几个概念(拷贝自官网http://weex.apache.org):

Weex 页面结构

界面展示、逻辑处理、设备能力使用、生命周期管理等部分。

Dom模型

Weex 页面通过类似 HTML DOM 的方式管理界面,首先页面会被分解为一个 DOM 树,每个 DOM 结点都代表了一个相对独立的 native 视图的单元。然后不同的视图单元之间通过树形结构组合在了一起,构成一个完整的页面。

组件

Weex 支持文字text、图片image、视频video等内容型组件,也支持 div、list、scroller 等容器型组件,还包括 slider、input、textarea、switch 等多种特殊的组件。Weex 的界面就是由这些组件以 DOM 树的方式构建出来的。

布局系统

Weex 页面中的组件会按照一定的布局规范来进行排布,我们这里提供了 CSS 中的盒模型、flexbox 和 绝对/相对/固定/吸附布局这三大块布局模型。

功能

Weex 提供了非常丰富的系统功能 API,包括弹出存储、网络、导航、弹对话框和 toast 等,开发者可以在 Weex 页面通过获取一个 native module 的方式引入并调用这些客户端功能 API。

生命周期

每个 Weex 页面都有其自身的生命周期,页面从开始被创建到最后被销毁,会经历到整个过程。这是通过对 Weex 页面的创建和销毁,在路由中通过 SDK 自行定义并实现的。

在移动办公开发中的实践

注:涉及代码均以Android端为例

(一)前端遵循weex移动应用的设计理念

weex认为一个具有高并行研发能力、动态化和标准化规范化的移动应用应该由以下几个方面构成:

这样的话,在构建一个完整的移动应用之前,先确定你的应用有多少页面,每个页面分别是什么 URL,页面之间的路由逻辑是怎样的,然后梳理整个移动应用需要的所有 API 和服务。最后通过 Weex 创建不同的页面,并分别进行开发、调试。

(二)构建自己的标杆工程

我们基于github上的Playground项目,构建了自己的标杆工程。

将不同的js文件用做常量、工具方法的定义。常量诸如url、版本开关、路由表。工具方法诸如Http get、post方法的封装、时间转换函数、加解密方法。

除了用vue封装页面,还封装了公用的样式,构建了常用的控件库。

(三)整合weex引擎,完善移动办公微应用的接入方案

挂接glide用于替换默认的picasso图库的实现,因为目前picasso的版本没法支持gif动图。另一个好处是,可以定制图库缓冲区的大小。

挂接自己的http适配器,适度复用Native的http实现并定制到weex中,同时这也是打通native登陆凭证和weex登陆凭证的必要一环。

在项目迭代中,扩展自定义控件。这块自定义控件特指通过WXSDKEngine.registerComponent()注册的Native控件。需要严格控制这部分控件的实现。基于以下几个方面考虑:

1.Native控件需要IOS、Android同时实现,增加了开发工作量。
2.页面使用了这种控件,老版本的应用就没法进行兼容,会需要提示用户升级。
3.开发者需要充分考虑纯vue的方式是否能实现,一般都是有方法的。

即使实现了Native控件,在后续weex引擎升级过程中,也需要持续关注,可能日后标准控件库会提供支持。

定义一套开放接口,通过WXSDKEngine.registerModule()注册,weex可以适度复用H5的开放接口实现。

注册自己的webview实现替换默认的webview。实现自己的文件下载器,文件选择器,支持电话号码、邮箱等链接的点击跳转。

(四)静态资源的缓冲和缓冲更新策略配置

静态资源(js、css、图片)默认不支持缓冲策略,导致使用微应用页面总是打开较慢,且浪费流量,没能达到离线web应用的顺滑操作体验。针对此问题,移动端和服务端均需做出调整。

前面我们讲到了,在客户端一侧,针对图片适配器我们设置了glide图库,且修改了缓冲配置。而针对静态页面的加载,weex的支撑模块是WXHttpManager和WXOkHttpDispatcher。如下图所示:

对defaultOkHttpClient进行缓冲路径和大小的配置。
在服务端一侧,配上Etag策略,如果不支持则配置较老的Last-Modified+If-Modified-Since策略。其实现效果如下:

第一次请求:

1.客户端发起 HTTP GET 请求一个文件。

2.服务器处理请求,返回文件内容和Headers,当然包括Etag(如"2e681a-6-5d044840"),状态码200。

第二次请求:

1.客户端发起 HTTP GET 请求同一个文件,这个时候客户端会附带一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d044840。

2.服务器判断发送过来的Etag和按云端文件计算出来的Etag匹配,说明静态资源未变更,直接返回304,通知客户端继续使用本地缓存。

需要补充的是,对于网络请求失败或是缓冲加载失败的情况,本地需要挂接回调方法处理,并定制加载失败页面,让用户在失败页面有机会点击刷新按钮进行重试。

(五)开放接口和接口权限控制

weex引擎加载的页面包括weex和H5两种,针对H5页面,通过Javascript Interface我们挂接与其他H5应用相同的一套开发接口。

这些是一部分我们给H5提供的开放接口,通过WXSDKEngine.registerModule()我们还另行包装了一份给weex调用。考虑到部分接口涉及用户隐私,如果应用内有要使用这部分接口,在应用启动时需要像微信一样有用户授权。

(六)打通Native、weex、H5的登陆凭证

我们应用的登陆凭证是保存在Cookie当中的,所以在Native、weex、H5中打通登陆凭证,实现单点登录(Single SignOn)我们做了以下几件事:

1.包装一个CookieManager,实现cookie的读写接口以兼容新老版本。

2.进程初始化时,初始化CookieManager;账号登出时,移除Cookies。

3.在WebView页面加载成功的回调,增加Cookie强制持久化写入的逻辑。Weex WebView也增加相同逻辑。

4.在Http请求、文件传输接口处增加Cookie的读写逻辑,特别要注意的是对重定向请求的处理,需要挂接自己的回调方法,读写Cookie。Weex对应的HttpAdapter和文件传输接口也需做相同修改。

(七)升级策略

无论是通过WXSDKEngine.registerModule() 注册的接口还是通过WXSDKEngine.registerComponent()注册的组件,都是在迭代版本中逐步添加进去的。考虑到兼容性,就存在一部分老版本客户端无法使用当前weex页面部分功能的问题,所以在weex页面需要增加平台最小版本号的控制逻辑,当客户端版本低于接口所需的最小版本时,要提示用户升级。

因为用户是可以选择忽略升级的,在每个组件和开放接口的使用点,也需要增加保护,无法使用时应提示是版本过低不支持的原因。

(八)错误的云监测

在Native可以通过接口 IWXRenderListener 中的 onException 回调方法监测render error、js exception、network error等。在Weex页面,则需要通过开放接口上报错误错误。这些错误最后都通过Native接口上报到云端,做到对用户问题的实时监控。

(九)屏幕适配

Weex是固定以750px作为虚拟屏幕宽度的,所有控件的实际大小要根据设备的屏幕大小进行等比缩放。例如,当一个按钮的尺寸在页面中设定为60x100px,而屏幕实际宽度为1080px,那么按钮的显示宽度则为60x1080/750 = 86px,高度则为100x1080/750 = 144px。

(十)引擎升级和平台兼容性的坑

作为一款需要商用的应用,在集成了weex引擎后,面临引擎升级的问题,尤其在阿里官方迭代版本较密集的现状下。强烈建议慎重升级!在引擎升级后要对已上线的应用做回归测试,我们遭遇到的实际状况是引擎升级支持了一些新功能,却把部分老控件、老接口、老页面给搞坏了。例如:

1.引擎升级到16版本Android端取系统时间接口,未携带当前时区偏移,到了18版本又好了。

2.18版本 IOS 横向翻页的页面切换效果会有垂直方向偏移。

3.vue本身是支持v-model给Input来赋值的,Android端的引擎升级到18之后这块功能突然又不支持了。

Weex引擎还存在一些平台兼容性的坑,例如:

1.页面恢复的广播事件,IOS和Android不一致,Android的事件名叫WXApplicationDidBecomeActiveEvent,IOS的叫viewWillAppear。

2.在做自定义组件的时候,需要页面上盖了一个蒙板控件,如果蒙板里没有内容,在Android端,蒙板不会消耗Touch事件,在IOS端,蒙板会消耗touch事件。为了解决这个问题,当蒙板上无内容的时候,需要把IOS端蒙板的透明度改成全透明。

3.http://weex.apache.org/cn/guide/use-vue.html中列举了一些vue支持,而weex暂不支持的情况,这个一开始我们也没注意到。

结语

Weex是一个新的开发框架,在技术革新的浪潮中,我们一方面要勇于尝试这样的新技术。另一方面,也要通过软件过程控制的方法来确保应用交付的稳定,实事求是、因地制宜的解决使用中面临的具体问题和挑战。软件工程学本身就是实践者的研究方法,唯有边实践边总结,才能在技术变革中始终不落下风。

作者简介

陈思佳,苏宁易购 IT 总部移动端高级架构师,主要负责苏宁移动通讯、IoT 、移动办公等项目研发工作。在移动端架构方面拥有十多年的实践经验,先后就职于华为无线产品线、Motorola GSG(Global Software Group)。精通移动端各类应用软件的编程架构、开发工具,喜欢钻研、持续改进各产品 Android、iOS 设备兼容性问题。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注