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 去啊

  1. 场景:基于mobile h5+native hybrid
  2. 地址:http://h5.m.taobao. com/trip/tuan/list/index.html
  1. 场景:基于native hybrid
  2. 地址: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

  1. 转换链接
  2. 判断链接类型(hybrid/http/rn/http)
  3. 添加公共参数
  4. app启动时获取routeMap

HybridBaseActivity(端处理)

 

 

 

 

  1. 初始化cordovaWebView
  2. checkCommonModule
    1. 检查hybrid文件映射表是否存在
    2. md5是否匹配等
  3. checkLazyModule
    1. 映射到本地文件
    2. 检查文件是否存在,是否解压
  4. loadUrl,打开文件
moduleName->h5rrc

HybridBaseActivity

(h5处理)

 

 

  1. 初始化cordova模块
  2. 加载其他公共模块

我是启动页

 

 

  1. 更新路由文件表
  2. 更新文件映射表
  3. 更新hybrid文件

还需要

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

hybrid

By leegend

hybrid

  • 181