JS与Native交互规范示例
标签: JS JavaScript Native
本文主要用于规范JS与Native(Android、iOS等)之间的交互,写了一个简单说明和示例,具体细节可待商榷。请注意,本文只是一个简单的协议制定说明,不作为最终的代码实现参考。
0. 数据格式说明
0.1、JS请求Native时传入的jsonObj的格式
{
func : "", // 调用的Native的方法的名称。Native根据该字段判断调用哪个函数。
callback : "", // 调用方法后的回调到JS的函数名。可以是任意自定义的函数名。
data : {} // 数据以json格式保存data字段中。所有传入参数均保存在该字段中。
}
0.2、Native回调JS时传回来的jsonObj的格式
(暂定保留上述的func和callback,例如方便html中将回调统一写在一个函数,用func区分。)
{
func : "", // 调用的Native的方法的名称。Native存在该方法才会生效
callback : "", // 调用方法后的回调到JS的函数名。可以是任意自定义的函数名
data : {}, // 数据以json格式保存data字段中。所有传出参数均保存在该字段中。
code : 200, // 状态码。200表示成功,其它表示失败,失败原因见msg。
// (code的其它值待定义,比如404可以代表调用的func不存在)
msg : ""
}
1. Web前端中间件 - JSNative.js [示例]
(function () {
var JSNative = window.JSNative = {};
JSNative.buildJsonObj = function(func, callback, dataJson){
var jsonObj = {
'func' : func,
'callback' : callback,
'data' : dataJson
};
return jsonObj;
};
/**
* 通用方法,可根据jsonObj中的func字段调用任意本地方法
*/
JSNative.callMethod = function(func, callback, dataJson){
var jsonObj = this.buildJsonObj(func, callback, dataJson);
// nativeInterface.Call(JSON.stringify(jsonObj));
// iOS and Android, very important, reserved to do.
// e.g.
// iOS : window.location.href = "xxxx";
// the format of "xxxx" may like "JSNative://methodName?data=xxxx";
// Android : window.location.href = "xxxx"; [or] JSInterfaceObject.xxxx(xxxx);
};
/**
* 调用后,客户端回调相关登录信息
*/
JSNative.forceInit = function(callback){
this.callMethod('forceInit', callback, {});
};
// ...
// ...
// ...
/**
* 调用后,客户端调用分享插件,并会回调相应分享情况
*/
JSNative.OnShare = function(callback, dataJson){
this.callMethod('OnShare', callback, dataJson);
};
// ...
// ...
// ...
/**
*页面加载完毕时,若用户已经登录,客户端回调该方法,回传参数token__regnumber(旧接口,保持不变)。
*需要监听的话请在外部复写。
*/
JSNative.init = function(id){
// 出参:token__regnumber[string]
};
/**
* 当webview首次打开或重新被show出来时调用。
* 需要监听的话请在外部复写。
*/
JSNative.webviewOnShow = function(fromWhat){
// 出参:from[int]:0首次进入webview,1从其他原生页面或后台唤醒回到webview
}
})();
2. HTML调用 [示例]
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<script src="JSNative.js"></script>
<script>
var shareInfoJson = {
title : '分享标题',
msg : '分享描述',
img : '分享icon地址',
url : '分享链接地址',
disable : '需要屏蔽的分享渠道'
};
JSNative.OnShare('onShareCallback', shareInfoJson);
// 此处的‘onShareCallback’回调名可以自定义
// or
// JSNative.callMethod('OnShare', 'onShareCallback', shareInfoJson);
// native will callback here because you call JSNative.OnShare
function onShareCallback(jsonObjStr){
console.log("onShareCallback->" + jsonObjStr);
var jsonObj = JSON.parse(jsonObjStr);
var func = jsonObj.func;
var callback = jsonObj.callback;
var dataJson = jsonObj.data;
var code = jsonObj.code;
var msg = jsonObj.msg;
var shareResultCode = dataJson.code;
// code:0失败,1成功,2用户取消操作;
// ...
}
// ...
// ...
// ...
JSNative.forceInit('onForceInitCallback');
// 此处的'onForceInitCallback'回调名可以自定义
// or
// JSNative.callMethod('forceInit', 'onForceInitCallback');
// native will callback here because you call JSNative.forceInit
function onForceInitCallback(jsonObjStr){
var jsonObj = JSON.parse(jsonObjStr);
var id = jsonObj.id;
// token__regnumber[string]:若用户已经登录,回传参数;若用户未登录,回传参数null或空
var version = jsonObj.version;
// App版本号
// ...
}
</script>
</html>
3.待优化的地方
3.1 HTML调用的callback直接传一个函数而不是函数名
解决方案:
(在中间件中处理)
① callback作为函数传入之后,保存一个键值对(key为func,value为该函数)。
② Native调用回调的时候统一回调到中间件中,如JSNative.onCallback(jsonObjStr)。
③ 中间件统一处理回调,按照JSNative.onCallback传回来的json值中的func,根据之前保存的[func, callback]键值对获取对应的callback 函数,然后对应分发回调到这个callback 函数中。
3.2 JS多次连续调用Native存在的覆盖问题
例如,如果是采用window.location传递的方式,很大可能存在间隔很短的连续两次调用的情况,此时会出现前者没被Native成功捕获之前被后者覆盖了。
解决方案:
(在中间件中处理)
① 每次任务调用都会先存队列再执行,执行完成收到Native的回调之后才将该任务出队,执行队列中的下一个任务。
② 为防止Native出现无回调或者回调时间过长导致堵塞的情况,当当前任务超过 [x] 秒未回调的情况,自动将其移出队列并执行下一个任务。
或者:
直接判断上次执行的时间,与当前时间对比,若未达到某个间隔 [x] 秒,则计算对应时差做延迟调用。