第一步:触发view层点击事件
点击获取手机系统信息按钮
首先调用了Page中的js方法,把事件传递到native层
@JavascriptInterface
public void publishHandler(final String event, final String params, final String viewIds) {
HeraTrace.d(TAG, String.format("publishHandler is called! event=%s, params=%s, viewIds=%s",
event, params, viewIds));
mHandler.post(new Runnable() {
@Override
public void run() {
if (mBridgeHandler != null) {
mBridgeHandler.publish(event, params, viewIds);
}
}
});
}
看看入参:
- event:custom_event_PAGE_EVENT
- params:
{
"data": {
"eventName": "getSystemInfo",
"data": {
"type": "tap",
"timeStamp": 9146482,
"target": {
"id": "",
"offsetLeft": 14,
"offsetTop": 436,
"dataset": {}
},
"currentTarget": {
"id": "",
"offsetLeft": 14,
"offsetTop": 436,
"dataset": {}
},
"detail": {
"x": 191.6666717529297,
"y": 465
},
"touches": [{
"identifier": 0,
"pageX": 194.33334350585938,
"pageY": 467,
"clientX": 194.33334350585938,
"clientY": 462
}],
"changedTouches": [{
"identifier": 0,
"pageX": 194.33334350585938,
"pageY": 467,
"clientX": 194.33334350585938,
"clientY": 462
}]
}
},
"options": {
"timestamp": 1562653184722
}
}
- viewIds:[]
切换到main线程,继续向下走,进入page
对应的方法
@Override
public void publish(String event, String params, String viewIds) {
HeraTrace.d(TAG, String.format("view@%s publish(), event=%s, params=%s, viewIds=%s",
getViewId(), event, params, viewIds));
if ("custom_event_DOMContentLoaded".equals(event)) {
onDomContentLoaded();
} else if ("custom_event_H5_LOG_MSG".equals(event)) {
HeraTrace.d(params);
} else {
onPageEvent(event, params);
}
}
进入页面事件方法
/**
* 页面事件
*
* @param event 事件名称
* @param params 参数
*/
private void onPageEvent(String event, String params) {
if (mEventListener != null) {
//转由Service层的订阅处理器处理
mEventListener.notifyServiceSubscribeHandler(event, params, getViewId());//这里有获取当前currentWebView的id,进行传递(193176380)
}
}
注意上面此时有viewid(193176380)的获取传递,这个是一系列操作之后,最后回传数据的关键点
继续向下走进入HeraActivity
中的对应方法
@Override
public void notifyServiceSubscribeHandler(String event, String params, int viewId) {
HeraTrace.d(TAG, String.format("notifyServiceSubscribeHandler('%s', %s, %s)",
event, params, viewId));
mAppService.subscribeHandler(event, params, viewId);
}
第二步:传递到逻辑层
继续进入AppService
的方法里面
/**
* Service层的订阅处理器处理事件
*
* @param event 事件名称
* @param params 参数
* @param viewId 视图id
*/
public void subscribeHandler(String event, String params, int viewId) {
HeraTrace.d(TAG, String.format("service subscribeHandler('%s',%s,%s)", event, params, viewId));
String jsFun = String.format("javascript:ServiceJSBridge.subscribeHandler('%s',%s,%s)",
event, params, viewId);
mServiceWebView.loadUrl(jsFun);
}
然后使用逻辑层的mServiceWebView调用相关api(到这里就相当于把page的事件由native传递到了逻辑服务层)
javascript: ServiceJSBridge.subscribeHandler('custom_event_PAGE_EVENT', {
"data": {
"eventName": "getSystemInfo",
"data": {
"type": "tap",
"timeStamp": 9146482,
"target": {
"id": "",
"offsetLeft": 14,
"offsetTop": 436,
"dataset": {}
},
"currentTarget": {
"id": "",
"offsetLeft": 14,
"offsetTop": 436,
"dataset": {}
},
"detail": {
"x": 191.6666717529297,
"y": 465
},
"touches": [{
"identifier": 0,
"pageX": 194.33334350585938,
"pageY": 467,
"clientX": 194.33334350585938,
"clientY": 462
}],
"changedTouches": [{
"identifier": 0,
"pageX": 194.33334350585938,
"pageY": 467,
"clientX": 194.33334350585938,
"clientY": 462
}]
}
},
"options": {
"timestamp": 1562653184722
}
}, 193176380)
3、逻辑层处理完毕后,继续回调js方法到native层
继续走,逻辑服务层处理完毕后,回调js,相当于把处理的结果传递到native层
@JavascriptInterface
public void invokeHandler(final String event, final String params, final String callbackId) {
HeraTrace.d(TAG, String.format("invokeHandler is called! event=%s, params=%s, callbackId=%s",
event, params, callbackId));
mHandler.post(new Runnable() {
@Override
public void run() {
if (mBridgeHandler != null) {
mBridgeHandler.invoke(event, params, callbackId);
}
}
});
}
入参:
- event:getSystemInfo
- params:{}
- callbackId:15
进入AppService
的方法
@Override
public void invoke(String event, String params, String callbackId) {
HeraTrace.d(TAG, String.format("api invoke, event=%s, params=%s, callbackId=%s",
event, params, callbackId));
Event e = new Event(event, params, callbackId);
mApisManager.invoke(e, this);
}
组装成Event,来到了Apimanager,找到了对应的方法进行调用
/**
* api功能调用
*
* @param event 封装了api名称,参数及回调函数id的对象
* @param bridge 与H5的通信接口
*/
public void invoke(Event event, IBridge bridge) {
ICallback callback = new ApiCallback(event, bridge);//创建一个回调
IApi api = APIS.get(event.getName());//首先从内置API查找这个API
if (api != null) {
CALLING_APIS.put(event, Pair.create(api, callback));
api.invoke(event.getName(), event.getParam(), callback);//如果能找到则直接调用,不能找到则继续尝试向扩展api请求
return;
}
if (mSender == null) {
HeraTrace.w(TAG,
String.format("cannot invoke extends api, sender is null, event:%s, params:%s",
event.getName(), event.getParam().toString()));
return;
}
CALLING_APIS.put(event, Pair.create(EMPTY_API, callback));
Bundle data = new Bundle();
data.putParcelable("event", event);
Message msg = Message.obtain();
msg.setData(data);
msg.what = RemoteService.INVOKE;
msg.replyTo = mReceiver;
try {
mSender.send(msg);
} catch (RemoteException e) {
HeraTrace.e(TAG, String.format("invoke send exception, event:%s, params:%s",
event.getName(), event.getParam().toString()));
callback.onFail();
}
}
本次使用的是内置jsapi,直接进入调用具体api的相应方法
@Override
public void invoke(String event, JSONObject param, ICallback callback) {
try {
JSONObject result = new JSONObject();
result.put("model", model);
result.put("pixelRatio", pixelRatio);
result.put("screenWidth", screenWidth);
result.put("screenHeight", screenHeight);
result.put("windowWidth", windowWidth);
result.put("windowHeight", windowHeight);
result.put("language", language);
result.put("version", version);
result.put("system", system);
result.put("platform", platform);
result.put("SDKVersion", SDKVersion);
callback.onSuccess(result);
} catch (JSONException e) {
HeraTrace.e(TAG, "systemInfo assemble result exception!");
callback.onFail();
}
}
native层调用方法结束后,传递结果到逻辑层
成功后进入AppService callback回调(这里就是把结果传递到逻辑服务层)
@Override
public void callback(String callbackId, String result) {
mServiceWebView.loadUrl(
String.format("javascript:ServiceJSBridge.invokeCallbackHandler(%s,%s)",
callbackId, result));
}
javascript: ServiceJSBridge.invokeCallbackHandler(15, {
"model": "SM-N9008V",
"pixelRatio": 3,
"screenWidth": 1080,
"screenHeight": 1920,
"windowWidth": 1080,
"windowHeight": 1677,
"language": "zh-CN",
"version": "1.0",
"system": "5.0",
"platform": "android",
"SDKVersion": "0.1",
"errMsg": "getSystemInfo:ok"
})
逻辑层再次包装数据,然后通过js传递回native层
然后逻辑服务层处理一下,再次通过js方法调用到native层
@JavascriptInterface
public void publishHandler(final String event, final String params, final String viewIds) {
HeraTrace.d(TAG, String.format("publishHandler is called! event=%s, params=%s, viewIds=%s",
event, params, viewIds));
mHandler.post(new Runnable() {
@Override
public void run() {
if (mBridgeHandler != null) {
mBridgeHandler.publish(event, params, viewIds);
}
}
});
}
event:custom_event_appDataChange
params:
{
"data": {
"data": {
"systemInfo": {
"model": "SM-N9008V",
"pixelRatio": 3,
"screenWidth": 1080,
"screenHeight": 1920,
"windowWidth": 1080,
"windowHeight": 1677,
"language": "zh-CN",
"version": "1.0",
"system": "5.0",
"platform": "devtools",
"SDKVersion": "0.1",
"errMsg": "getSystemInfo:ok"
}
}
},
"options": {
"timestamp": 1562654730565
}
}
viewIds = "[193176380]"
继续进入服务层的方法
@Override
public void publish(String event, String params, String viewIds) {
HeraTrace.d(TAG, String.format("service publish(), event=%s, params=%s, viewIds=%s",
event, params, viewIds));
if ("custom_event_serviceReady".equals(event)) {//service.html加载完成,初始化应用的配置信息
onEventServiceReady(params);
} else if ("custom_event_appDataChange".equals(event)) {
onEventAppDataChanged(event, params, viewIds);
} else if ("custom_event_H5_LOG_MSG".equals(event)) {
HeraTrace.d(params);
} else if (event.contains("custom_event_canvas")) {
onEventAppDataChanged(event, params, viewIds);
}
}
进入PagerManager
/**
* 订阅事件处理器
*
* @param event 事件名称
* @param params 参数
* @param viewIds 需要订阅的视图id
*/
public void subscribeHandler(String event, String params, int[] viewIds) {
if (viewIds == null || viewIds.length == 0) {
HeraTrace.d(TAG, "page subscribeHandler failed, viewIds is empty");
return;
}
int count = getPageCount();
for (int i = 0; i < count; i++) {
Page page = getPageAt(i);
page.subscribeHandler(event, params, viewIds);
}
}
遍历所有page 调用subscribeHandler 方法
Page层方法
/**
* Page层的订阅处理器处理事件
*
* @param event 事件名称
* @param params 参数
* @param viewIds 视图id数组
*/
public void subscribeHandler(String event, String params, int[] viewIds) {
HeraTrace.d(TAG, String.format("view@%s subscribeHandler('%s',%s)", getViewId(), event, params));
if (viewIds == null || viewIds.length == 0) {
return;
}
int count = mWebLayout.getChildCount();
for (int i = 0; i < count; i++) {
SwipeRefreshLayout refreshLayout = (SwipeRefreshLayout) mWebLayout.getChildAt(i);
PageWebView webView = (PageWebView) refreshLayout.getChildAt(0);
for (int viewId : viewIds) {
if (viewId == webView.getViewId()) {
String jsFun = String.format("javascript:HeraJSBridge.subscribeHandler('%s',%s)",
event, params);
webView.loadUrl(jsFun);
break;
}
}
}
}
最后根据viewId 找到对应View回调数据
然后在遍历Page中的Webview 找到id对应的webview,然后调用js,把结果传递给页面渲染。
javascript: HeraJSBridge.subscribeHandler('custom_event_appDataChange', {
"data": {
"data": {
"systemInfo": {
"model": "SM-N9008V",
"pixelRatio": 3,
"screenWidth": 1080,
"screenHeight": 1920,
"windowWidth": 1080,
"windowHeight": 1677,
"language": "zh-CN",
"version": "1.0",
"system": "5.0",
"platform": "devtools",
"SDKVersion": "0.1",
"errMsg": "getSystemInfo:ok"
}
}
},
"options": {
"timestamp": 1562654730565
}
})