您的位置:首页 > 编程语言 > Java开发

【phonegap】使用的java与js互相调用的原理

2013-11-06 15:55 447 查看
http://blog.sina.com.cn/s/blog_6e4d9a9b0101ny26.html

Phonegap使用的java与js互相调用的原理。phonegap实现的模型刚也说了,有同步和异步两种。js实现的api,所以是js先会调用java代码,然后再返回给js。对于同步的而言,就是js调用java,然后java返回一个结果作为返回值。对于异步的而言,可能js掉了很多java代码,但是立即返回,然后java代码执行结束后再回调js代码,这里就涉及到js调java,然后java再调用js。

对于js调用java:

js调用java的入口是通过在js中调用prompt方法,这很奇怪吧,这个方法本来是让浏览器弹出个输入框的。我当初找了好久也没发现phonegap到底怎么搞得的让js调用java的代码,后来看到一会觉得该是这个方法,但是这是一个浏览器的客户端自己的东西,而且怪异的是浏览器并没有弹出输入框,后来终于发现。

在DroidGap.java中有个hack,重载了WebviewClient的onJsPrompt方法,然后执行了自己的逻辑。也就是js调用prompt的时候,java端浏览器代码接受到这个,然后在响应的处理函数中根据传过来的参数,实现了一些特别的逻辑。可以从这个方法的注释上看出一二。
private LinkedList javascript;


服务器保存要回调的js的代码,供js客户端取回,这里java端是服务器端,js端是客户端,服务器端不可能请求客户端做啥,是b/s模型,所以phonegap实现了两种服务模型,一种是轮询,一种是XHR异步回调,也就是Ajax的模型。src/com/phonegap/CallbackServer.java是回调服务器的代码所在处。从类的注释中可以看到。
This class provides a way for Java to run JavaScript in the web page that has loaded PhoneGap.
The CallbackServer class implements an XHR server and a polling server with a list of JavaScript statements
that are to be executed on the web page.


CallbackServer提供的这两种模型,一种是XHR,一种是轮询,轮询很简单了,callbackserver服务器端,有一个保存回调js的列表,前面所说,然后每隔一段时间客户端的js会询问一次服务器,是否有需要回调的js,如果有则调用,然后每隔一段时再查询一次服务器。而基于XHR的,其实这个就是ajax用的机制了,js发起一个异步请求,然后服务器会在返回数据之前保持住这个连接,当返回数据就位后,服务器给请求客户端返回数据,然后关闭连接。然后客户端接受并且处理。

刚说了服务器端的代码实现,现在来看一下客户端js的相关代码。
PhoneGap.JSCallback = function() {
...
xmlhttp.open("GET", "http://127.0.0.1:"+PhoneGap.JSCallbackPort+"/"+PhoneGap.JSCallbackToken , true);
xmlhttp.send();
}

[/code]

这个是XHR模型的代码,客户端js使用xhr请求服务器来获取js代码,进行回调。
PhoneGap.JSCallbackPolling = function() {
...
var msg = prompt("", "gap_poll:");
if (msg) {
setTimeout(function() {
try {
var t = eval_r(""+msg);
}
catch (e) {
console.log("JSCallbackPolling: Message from Server: " + msg);
console.log("JSCallbackPolling Error: "+e);
}
}, 1);
setTimeout(PhoneGap.JSCallbackPolling, 1);
}
else {
setTimeout(PhoneGap.JSCallbackPolling, PhoneGap.JSCallbackPollingPeriod);
}
}

[/code]

这个是轮询方式的,可以看到客户端每隔PhoneGap.JSCallbackPollingPeriod段时间,就请求一次服务器(通过prompt("","gap_poll:");)。

******************************************[b]************************************************************************

[/b]

iOS:

通过让本地代码拦截JavaScript中调用的 window.location=”gap://Class.method/args”命令,来实现从JavaScript到本地代码之间的通信。在本地 代码拦截该命令后,解析获取的参数,然后调用对应的类、方法并传递参数。对应的,使用 UIWebView.stringByEvaluatingJavaScriptFromString来实现本地代码调用JavaScript。

Android:

通 过拦截JavaScript的prompt命令实现从JavaScript到本地代码的通信。JavaScript prompt命令默认会弹出对话框,而PhoneGap的Android本地代码会拦截该对话框,并进一步取得JavaScript数据。相应 的,Android上的PhoneGap内部,使用Java实现了一个HTTP服务器,通过持久性的XHR连接,JavaScript可以不断轮询内部 XHR服务器存储的信息,从而实现了从Java到JavaScript方向的通信。

BlackBerry 4.x:

JavaScript 与本地代码之间的唯一通信方式是通过document.cookie实现的。JavaScript设定Cookie,本地代码从Cookie中获取信息。 对应的,本地代码也可以设定Cookie,允许JavaScript从Cookie中获取本地代码信息。

BlackBerry WebWorks:

新 的BlackBerry WebWorks SDK更好地支持了Java与JavaScript之间的交互通信。通过ScriptEngine.addExtension,Java对象可以被暴露给 JavaScript,而对应的Java可以使用ScriptEngine.executeScript来调用JavaScript。

Windows Phone 7:

在Windows Phone 7中,JavaScript通过window.external.Notify可以将信息发送给本地代码。而相应的,WebBrowser.InvokeScript允许本地代码调用JavaScript。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: