JS注册事件,Java调用并返回结果到Java
- JS注册事件
Jockey.on("getXXX", function(payload, complete) {...}
JS中Jockey内部变量 listeners中以getXXX为id存放一个数组,并将这个function push到数组中。
- Java调用JS中已注册的事件
Jockey jockey = JockeyImpl.getDefault();
jockey.send("show-test", webView, new JockeyCallback() {...})
Java层以请求的次序为id将callback函数存放到 JockeyImpl中的_callbacks变量中,将请求参数转换为 "javascript:Jockey.trigger("%s", %d, %s)"的形式传递到 WebView中执行
"javascript:Jockey.trigger(\"%s\", %d, %s)"
WebView 执行js函数Jockey.trigger("%s", %d, %s),取出listeners中已注册的getXXX并执行数组中的function
- JS回调Java中的callback对象
对于需要获取执行结果的情况,JS会回调Java中的callback对象
JS层执行
window.location.href = "jockey://" + type(callback) + "/" + envelope.id + "?" +
encodeURIComponent(JSON.stringify(envelope))
在JockeyWebViewClient中的shouldOverrideUrlLoading(WebView view, String url)中拦截"jockey"scheme (jockey://callback/0?%7B%2%7D),发现是callback类型,解析出messageId转交Jockey处理,从_callbacks中找到messageId对应的callback执行并从_callbacks中移除。
- java调用JS中已注册的方法
最终执行结果会通知到JS层,但是源码中并没有接受这个结果。
Java注册事件,JS调用并返回结果到JS
1.Java注册事件
Jockey jockey = JockeyImpl.getDefault();
jockey.on("log", new JockeyHandler() {...})
JockeyImpl的_listeners中,以log为id push一个复合处理器(CompositeJockeyHandler),并将这个JockeyHandler放到CompositeJockeyHandler中
@Override
public void on(String type, JockeyHandler... handler) {
if (!this.handles(type)) {
_listeners.put(type, new CompositeJockeyHandler());
}
_listeners.get(type).add(handler);
}
- JS调用Java中已注册的事件
Jockey.send("log", function(){...})
JS层Jockey以请求的messageCount为id将callback函数存放到callbacks中。然后将请求参数拼接成新的地址设置给浏览器
window.location.href = "jockey://" + type(event) + "/" + envelope.id + "?" +
encodeURIComponent(JSON.stringify(envelope));
JockeyWebViewClient中shouldOverrideUrlLoading(WebView view, String url)拦截带"jockey"scheme (jockey://event/0?%7B%2%7D),发现是event类型,解析出messageId转交Jockey处理
Java层Jockey从_listeners中找到已注册的"log"执行CompositeJockeyHandler中的JockeyHandler,最后onComplete回调JS的callback
- Java回调JS中的callback对象
执行callback对象会在WebView中执行 "javascript:Jockey.triggerCallback("%d")",WebView调用JS中Jockey脚本中对应的triggerCallback function,最终从callbacks 中找到messageId对应的callback并执行。
整个流程分析完毕,这个框架设计的非常有条理,JS层和Java层有点镜像的感觉,整个源码看完后对于Java和JS交互会有更深层次的体会。
项目地址 https://github.com/kevin-mob/jockeyjs,流程图是用PlantUML编写,也一同放到了项目里面。