Hybrid
- 简介
- 怎么做
- 虚拟域
- 资源动态更新
- 与native的互调
- 研发效率
- Hybrid过程
- 其他
简介
- 将web静态资源预装到App中的混合模式移动应用
Hybrid是什么?
web app
native app
hybrid app
简介
- 拥有web app多端兼容的优势
- 解决web app访问静态资源速度慢的问题
- 解决native app更新实效差的问题
- etc.
区别于web app和native app
怎么做
- 虚拟域
- 资源动态更新
- cordova插件机制
- 其他
怎么做 虚拟域
- 构建一个虚拟的域名,使App在此域名下的资源请求可从本地获取
怎么做 虚拟域
jdbclient://rrc/h5rrc
scheme:jdbclient
host:rrc
path:h5rrc
虚拟域管理
hybrid://www/h5rrc
其他处理
端外打开
端内进入
native/webview
加载本地资源
怎么做 虚拟域
调起url
H5离线包
Hybrid文件映射表
App
CDN
映射表接口
Hybrid发布平台
(编译好的静态文件)
虚拟域等处理
WebView
打开页面
怎么做 虚拟域
方案对比
JDB
ALI 去啊
- 场景:基于mobile h5+native hybrid
- 地址:http://h5.m.taobao. com/trip/tuan/list/index.html
- 场景:基于native hybrid
- 地址:jdbclient://rrc/h5rrc
怎么做 资源动态更新
用户终端App
启动/访问webview
CDN
映射表接口
Hybrid发布平台
(编译好的静态文件)
gitlab
检查映射表更新
下载
怎么做 资源动态更新
用户终端App
启动/访问webview
CDN
映射表接口
Hybrid发布平台
(编译好的静态文件)
gitlab
检查映射表更新
下载
(懒加载)
映射表接口
file
file
...
file
file
...
md5
对比
非懒加载
请求下载新文件
怎么做 资源动态更新
更新时机
- 启动app(真!)
-
访问hybrid页面
- 启动时保存文件失败
- 下载common模块
- 下载common模块失败
问题
- 不杀死app如何更新?
怎么做 cordova插件机制
CordovaPlugin
定制化Plugin1
CordovaPlugin
定制化Plugin2
CordovaPlugin
...
配置文件
config.xml
CordovaWebview
js调用组件
prompt
拦截
插件映射
注册插件
调用插件
返回结果
注册插件过程
调用插件过程
怎么做 cordova插件机制
配置文件
config.xml
- id: 插件的标识
- name:插件的名称
- description:描述信息
- access:可访问的域白名单
- allow-intent:可访问的url白名单
-
feature:插件参数
<?xml version='1.0' encoding='utf-8'?>
<widget
id="com.rrx.jdb"
version="0.0.1">
<preference
name="loglevel"
value="DEBUG" />
<allow-intent href="market:*" />
<name>jiedaibao</name>
<description></description>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<allow-navigation href="*" />
<feature name="PayCashier">
<param
name="android-package"
value="com.rrh.jdb.hybrid.plugin.paycashier.PayCashierPlugin"/>
</feature>
<feature name="ClearHistory">
<param
name="android-package"
value="com.rrh.jdb.hybrid.plugin.clearhistory.ClearHistoryPlugin"/>
</feature>
怎么做 cordova插件机制
CordovaPlugin
定制化Plugin1
/*
* 端内插件代码
*/
public class PayCashierPlugin extends CordovaPlugin {
private CallbackContext mCallbackContext;
private LocalBroadcastManager lbm = LocalBroadcastManager
.getInstance(JDBApplication.getContext());
/** 增加operatType字段来区分打开收银台和选择银行卡界面 0为收银台 1为银行卡 */
private String OPERATE_TYPE = "operatType";
@Override
public boolean execute(String action, JSONArray jsonArray,
final CallbackContext callbackContext) {
}
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
}
}
怎么做 cordova插件机制
前端
cordova封装
/*
* js之cordova封装
*/
cordova.define("com.jiedaibao.paycashier.PayCashier", function (require,
exports, module) {
var exec = require('cordova/exec');
module.exports = {
payCashier : function(tradeID, amount, ext, businessType,
successCallback, errorCallback) {
exec(
successCallback,
errorCallback,
'PayCashier',
'payCashier',
[{
"tradeID": tradeID,
"amount": amount,
"ext": ext,
"businessType":businessType
}]
);
}
}
}
);
怎么做 cordova插件机制
js
调用native插件
/*
* js调用插件
*/
PayCashier.payCashier(
1,
100,
'',
JSON.stringify({}),
function(ret) {
$scope.isLocked = false;
var result;
if (typeof ret == 'object') {
result = ret;
} else {
result = JSON.parse(ret);
}
if (result.status * 1 === 0) {
location.href = '#/successResult?amount=' + result.amount;
}
},
function() {
tools.toast('支付失败!!!');
$scope.isLocked = false;
}
);
怎么做 cordova插件机制
/*
* js之cordova封装
*/
cordova.define("com.jiedaibao.paycashier.PayCashier", function (require,
exports, module) {
var exec = require('cordova/exec');
module.exports = {
payCashier : function(tradeID, amount, ext, businessType,
successCallback, errorCallback) {
exec(
successCallback,
errorCallback,
'PayCashier',
'payCashier',
[{
"tradeID": tradeID,
"amount": amount,
"ext": ext,
"businessType":businessType
}]
);
}
}
}
);
/*
* 端内插件代码
*/
public class PayCashierPlugin extends CordovaPlugin {
private CallbackContext mCallbackContext;
private LocalBroadcastManager lbm = LocalBroadcastManager
.getInstance(JDBApplication.getContext());
/** 增加operatType字段来区分打开收银台和选择银行卡界面 0为收银台 1为银行卡 */
private String OPERATE_TYPE = "operatType";
@Override
public boolean execute(String action, JSONArray jsonArray,
final CallbackContext callbackContext) {
}
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
}
}
整个对象
研发效率 Cordova+Ionic+AngularJS
- Cordova
- 跨平台插件,通信方式
- Ionic
- 预置仿native的ui组件
- 基于AngularJS
- AngularJS
- 双向数据绑定
- MVW(Whatever)分层
- directive,filter等



研发效率 编译脚本(task做了什么?)
- browserify
- js模块化加载
- 替换js文件中的{{(.+Api)}}请求地址
- js代码压缩
-
styles
- css文件整合
- css浏览器前缀
- sass
-
images
- 压缩图片



研发效率 编译脚本(task做了什么?)
- external
- 拷贝lib、common文件夹
- 拷贝cordova封装文件夹
- 拷贝hybrid-mock
-
markup
- 添加hybrid mock到页面
- help
- 帮助指令



研发效率 编译脚本(task做了什么?)
-
browserSync
- 启动本地服务
- mockApi
-
clean
- 清除dist文件夹
- watch
- 监听文件更新
-
index
- 总入口


Hybrid过程 输入地址到呈现发生了什么?

客户端
人人催按钮
RouteManager
jdbclient://rrc/h5rrc
- 转换链接
- 判断链接类型(hybrid/http/rn/http)
- 添加公共参数
- app启动时获取routeMap
HybridBaseActivity(端处理)
- 初始化cordovaWebView
- checkCommonModule
- 检查hybrid文件映射表是否存在
- md5是否匹配等
- checkLazyModule
- 映射到本地文件
- 检查文件是否存在,是否解压
- loadUrl,打开文件
moduleName->h5rrc
HybridBaseActivity
(h5处理)
- 初始化cordova模块
- 加载其他公共模块
我是启动页
- 更新路由文件表
- 更新文件映射表
- 更新hybrid文件
还需要

- 不需要app重启即可更新的动态更新机制(已解决,4小时)
- 页面配置平台(ing)
- hybrid性能优化,性能监控(crash)
- 数据统计?
hybrid
By leegend
hybrid
- 181