PhoneGap 是一个移动开发框架。通过 PhoneGap,开发者可以使用 JavaScript 调用手机的原生功能,例如,获取经纬度,让手机振动等。
主页 http://www.phonegap.com/ 。
源码 https://github.com/phonegap/phonegap-android 。
PhoneGap 在早期,应该是使用 WebView 的 addJavaScriptInterface 方法,来为 JS 提供调用原生功能可能。addJavaScriptInterface ,可以将一个 Java 对象绑定到一个 JS 对象。是的,JS对象可以调用 Java方法。但在 PhoneGap 1.0.0 这个版本中,PhoneGap 改变了方法。
以振动功能为例,我们可以看一下程序调用的流程:
1 在 JS 中,启动命令 main.js / navigator.notification.vibrate(0);
notification.js / Notification.vibrate.vibrate 中执行了 PhoneGap.exec(null, null, "Notification", "vibrate", [mills]);
phonegap.js / PhoneGap.exc 中执行了 var r = prompt(PhoneGap.stringify(args), "gap:"+PhoneGap.stringify([service, action, callbackId, true]));
这时,WebView 就会企图弹出一个窗口。这时使用 android 提供的 WebChromeClient 的 API 就可以截获 WebView 的这个动作 。
2 JAVA 中,处理命令
WebView 的 WebChromClient 实现了下面这个函数:
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
在 onJsPrompt 中执行了 String r = pluginManager.exec(service, action, callbackId, message, async);
PlugManager 会根据收到参数,将命令分发给特定的 Plugin。这个例子中,接收的 plugin 是:Notification。
落实到 Notification 的 exec 函数:会执行这一行: this.vibrate(args.getLong(0));
振动的实现为:
public void vibrate(long time){
// Start the vibration, 0 defaults to half a second.
if (time == 0) {
time = 500;
}
Vibrator vibrator = (Vibrator) this.ctx.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(time);
}
3 Java 处理完后的数据,需要给 JS 一个反馈:这里 PhoneGap 使用了一个在客户端本地实现的 XHRServer,具体到代码中就是一个JAVA 类 CallbackServer。
分两个部分介绍其行为:
本地 XHRServer,
思想是,后台每执行完一个命令,都会将结果存在 CallbackServer 中的一个链表中,具体为CallbackServr的 private LinkedList<String> javascript;
这个结果其实是一段字符串表示的 JS 函数调用。例如检测网络调用的结果为:PhoneGap.callbackSuccess('Network Status1',{status:1,message:"wifi",keepCallback:true});
XHRServer 的行为很简单,只要有请求来,就把链表中的最先进来的提出来,返回给客户端。没有请求来,则 10秒钟返回一个空的回复,以维持XHRServer。
Webview 作为客户端:
在 WebView 中,会有一个轮询机制,这可以参考 PhoneGap.JSCallack 和 PhoneGap.JSCallbackPolling 两个函数来访问 XHRServer。XHRServer,返回的结果就是 WebView 需要调用的 JS 函数。 在 JS 中,eval() 函数,将返回的结果变为一个可以执行的对象,在 Webview 中执行,可以认为这即是回调函数 Callback。这也是为什么 PhoneGap 为何命名 XHRServer 为 CallbackServer 的原因。
posted on 2011-09-20 10:20
lincode 阅读(3728)
评论(1) 编辑 收藏 所属分类:
android