Hera框架小程序 调用api流程分析

第一步:触发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
    }
})

你可能感兴趣的:(Hera框架小程序 调用api流程分析)