当然,qq作为一个浏览器容器,不应该关注业务的登录,他这样做是没问题的,但是我们自己的一个H5子应用如果登录了的话,便希望将这个登录态同步到native,这里如果native去监控cookie的变化就太复杂了,通用的方案是:
Hybrid APP中,所有的登录走Native提供的登录框
每次打开webview native便将当前登录信息写入cookie中,由此前端就具有登录态了,登录框的唤起在接口处统一处理:
无论成功与否皆会关闭登录框 3 参数包括: 4 success 登录成功的回调 5 error 登录失败的回调 6 url 如果没有设置success,或者success执行后没有返回true,则默认跳往此url HybridUI.Login = function (opts) { 9 }; requestHybrid({ 12 tagname: 'login', 13 param: { 14 success: function () { }, 15 error: function () { }, 16 url: '...' 17 } 18 }); HybridUI.logout = function () { 21 };
账号切换&注销账户注销本没有什么注意点,但是因为H5 push了一个个webview页面,这个重新登录后这些页面怎么处理是个问题。
我们这边设计的是一旦重新登录或者注销账户,所有的webview都会被pop掉,然后再新开一个页面,就不会存在一些页面展示怪异的问题了。
公共业务的设计-体系化在Hybrid架构中(其实就算在传统的业务中也是),会存在很多公共业务,这部分公共业务很多是H5做的(比如注册、地址维护、反馈等,登录是native化了的公共业务),我们一个Hybrid架构要真正的效率高,就得把各种公共业务做好了,不然单是H5做业务,效率未必会真的比Native高多少。
底层框架完善并且统一后,便可以以规范的力量限制各业务开发,在统一的框架下开发出来的公共业务会大大的提升整体工作效率,这里以注册为例,一个公共页面一般来说得设计成这个样子:
公共业务代码,应该可以让人在URL参数上对页面进行一定定制化,这里URL参数一般要独特一些,一面被覆盖,这个设计适用于native页面
URL中会包含以下参数:
① _hashead 是否有head,默认true
② _hasback 是否包含回退按钮,默认true
③ _backtxt 回退按钮的文案,默认没有,这个时候显示为回退图标
④ _title 标题
⑤ _btntxt 按钮的文案
⑥ _backurl 回退按钮点击时候的跳转,默认为空则执行history.back
⑦ _successurl 点击按钮回调成功时候的跳转,必须
只要公共页面设计为这个样子,就能满足多数业务了,在底层做一些适配,可以很轻易的一套代码同时用于native与H5,这里再举个例子:
如果我们要点击成功后去到一个native页面,如果按照我们之前的设计,我们每个Native页面皆已经URL化了的话,我们完全可以以这种方向跳转:
1 requestHybrid({ 2 tagname: 'forward', 3 param: { 4 topage: 'nativeUrl', 5 type: 'native' 6 } 7 });
这个命令会生成一个这样的url的链接:
_successurl == hybrid://forward?param=%7B%22topage%22%3A%22nativeUrl%22%2C%22type%22%3A%22native%22%7D
完了,在点击回调时要执行一个H5的URL跳转:
window.location = _successurl
而根据我们之前的hybrid规范约定,这种请求会被native拦截,于是就跳到了我们想要的native页面,整个这一套东西就是我们所谓的体系化:
离线更新根据之前的约定,Native中如果存在静态资源,也是按频道划分的:
webapp //根目录 ├─flight ├─hotel //酒店频道 │ │ index.html //业务入口html资源,如果不是单页应用会有多个入口 │ │ main.js //业务所有js资源打包 │ │ │ └─static //静态样式资源 │ ├─css │ ├─hybrid //存储业务定制化类Native Header图标 │ └─images ├─libs │ libs.js //框架所有js资源打包 │ └─static //框架静态资源样式文件 ├─css └─images
我们这里制定一个规则,native会过滤某一个规则的请求,检查本地是否有该文件,如果本地有那么就直接读取本地,比如说,我们会将这个类型的请求映射到本地:
//===>> file ===> flight/static/hybrid/icon-search.png
这样在浏览器中便继续读取线上文件,在native中,如果有本地资源,便读取本地资源:
但是我们在真实使用场景中却遇到了一些麻烦。
增量的粒度其实,我们最开始做增量设计的时候就考虑了很多问题,但是真实业务的时候往往因为时间的压迫,做出来的东西就会很简陋,这个只能慢慢迭代,而我们所有的缓存都会考虑两个问题:
① 如何存储&读取缓存
② 如何更新缓存
浏览器的缓存读取更新是比较单纯的:
浏览器只需要自己能读到最新的缓存即可