PhoneGap原理分析
PhoneGap提供了Native Api的支持(如:重力感应、相机、联系人、文件、地址位置…),
比如要用js获取本机的联系人,可以用:
var options = new ContactFindOptions();
options.filter = "李";
options.multiple = true;
var fields = ["displayName", "phoneNumbers", "emails"];
navigator.contacts.find(fields, onSuccess, onError, options);
就样就可以获取到名称中包含‘李’的人了。
现在PhoneGap似乎已经成为apache开源项目
PhoneGap主页
apache cordova(android版)
http://incubator.apache.org/cordova/index.html
源码:https://github.com/apache/incubator-cordova-android
文档:https://github.com/apache/incubator-cordova-docs

org.apache.cordova.CordovaChromeClient.onJsConfirm(WebView view, String url, String message, final JsResult result);
这个方法会拦截html页面发送过来的Native Api请求(调用window.prompt()),然后交由对应的Plugin处理。
1. 服务器流程:
1) 用Plugin来提供服务供客户端js调用,参见PhoneGap的plugin配置文件:plugins.xml,如果要自己定制plugin,需要继承Plugin类并在plugins.xml中进行相应的配置。
2) 同步/异步
服务器根据2个参数来判断是同步OR异步,
客户端传过来的异步参数 + 服务端Plugin.isSynch(action)
如果是同步,则直接把处理请求并把响应写到客户端
如果是异步,则启动一个线程来处理,处理完后,将结果通过CallbackServer写到客户端。
3) CallbackServer相当于xmlHttpResponse,负责将数据异步写到客户端。它在内部会有一个socket监听,不停的接收来自于客户端的请求,
如果发现变量(javascript)中有数据的话,就写到客户端,
如果没有,则睡眠10s,10s后,如果有数据,则写到客户端,否则写一个404异常到客户端然后此次连接中断,重新接收新的客户端请求(客户端有一个轮询,如果服务端返回404,则客户端会每隔一段时间请求一次服务器)
4) 服务器异步返回给客户端的数据格式:
// 正常处理后的返回(Contacts2表示请求的ID,客户端根据这个ID调用对应的回调函数):
// 其中,红色的json对象是PluginResult对象(自定义plugin时也需要返回一个PluginResult对象)
// 黑色的javascript脚本是经过PluginManager.exec()包装过的,被客户端eval解释执行。
HTTP/1.1 200 OK
require('cordova').callbackSuccess('Contacts2',{status:1,message:[{"displayName":"%E6%9D%8E%E6%8C%9A","id":"44","rawId":"46","phoneNumbers":[{"type":"mobile","value":"18608020312","id":"92","pref":false}]}],keepCallback:false});
// 404保持连接的返回
HTTP/1.1 404 NO DATA
2. 客户端流程:
1) 调用Native Api
PhoneGap的js框架,在调用Native Api时,都会汇聚到exec这个方法:
define('cordova/exec', function(require, exports, module) {
var cordova = require('cordova');
module.exports = function(success, fail, service, action, args) {
try {
var callbackId = service + cordova.callbackId++;
if (success || fail) {
cordova.callbacks[callbackId] = {
success: success,
fail: fail
};
}
//这里给服务器发送请求,
//service表示采用哪个
//true表示采用异步调用
//服务器会判断这个service+action是否支持异步调用
//如果是同步,则服务器会立即返回处理结果到变量r
//如果是异步,则服务器返回空串””
var r = prompt(JSON.stringify(args),
"gap:" + JSON.stringify([service, action, callbackId, true]));
// If a result was returned
if (r.length > 0) {
……
}
} catch(e2) {
console.log("Error: " + e2);
}
};
});
2) 异步回调
define('cordova/plugin/android/callback', function(require, exports, module) {
……
callback = function() {
……
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
// 服务器端返回结果数据,客户端通过eval执行结果
// 再次往服务器发起请求。
if (xmlhttp.status === 200) {
// Need to url decode the response
var msg = decodeURIComponent(xmlhttp.responseText);
setTimeout(function() {
try {
var t = eval(msg);
} catch(e) {
console.log("JSCallback: Message from Server: " + msg);
console.log("JSCallback Error: " + e);
}
}, 1);
setTimeout(callback, 1);
}
// 服务器与客户端约定如果404,则客户端接着请求服务器,10s内,
// 如果客户端调用了Native Api,则服务器服务数据后,进入上面200的逻辑,
// 如果客户端没调用,则服务器依然返回404,如此循环。
else if (xmlhttp.status === 404) {
setTimeout(callback, 10);
}
……
}
};
xmlhttp.open("GET", "http://127.0.0.1:" + port + "/" + token, true);
xmlhttp.send();
};
});
3. 自定义plugin流程:
1) 服务端:
继承com.phonegap.api.Plugin类,重写execute方法
public PluginResult execute(String action, JSONArray args, String callbackId){}
在plugins.xml中配置我们的类,
<plugin name="LoginPlugin" value="com.synnex.plugin.LoginPlugin"/>
NOTE:
isSynch()方法是告诉PhoneGap框架,此处理是同步OR异步,true表示同步,false表示异步,默认为flase
在同步处理的时候,不要去做UI操作(如:修改EditText内容),可以交由Handler更新UI。
2) 客户端:
// 向PhoneGap注册服务
var LoginPlugin = function(){};
LoginPlugin.prototype.dologin = function(successCallback, failureCallback, args)
{
//”LoginPlugin”需要与服务端xml中的名称一致。
//”login”即传给服务端excute()方法的action参数
//args必须是一个数组,对应execute()方法的args参数
return cordova.exec(successCallback, failureCallback, "LoginPlugin", "login", args);
};
cordova.addConstructor(function()
{
cordova.addPlugin("loginPlugin", new LoginPlugin());
});
// 调用时:
// 此处loginPlugin为上面addPlugin的第1个参数,
// dologin为上面LoginPlugin函数的方法名
// msg为服务端返回的数据。
plugins.loginPlugin.dologin(function(msg)
{
navigator.notification.alert(msg, undefined, "Success", "OK");
}, function(msg)
{
navigator.notification.alert(msg || "Error", undefined, "Failure", "OK");
}, [{username: "troyz", password: "123456"}]);
PhoneGap原理分析的更多相关文章
- HTML5 移动应用开发环境搭建及原理分析
开发环境搭建: 一.Android 开发平台搭建 安装java jdk:\\10.194.151.132\Mewfile\tmp\ADT 配置java jdk 1) 新建系统变量,JAVA_HOME ...
- Handler系列之原理分析
上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...
- Java NIO使用及原理分析(1-4)(转)
转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...
- 原子类java.util.concurrent.atomic.*原理分析
原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...
- Android中Input型输入设备驱动原理分析(一)
转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...
- 转载:AbstractQueuedSynchronizer的介绍和原理分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- Camel运行原理分析
Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...
- NOR Flash擦写和原理分析
NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...
- 使用AsyncTask异步更新UI界面及原理分析
概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
随机推荐
- magento缓存系列详解:clean cache
cache是一个很大的概念,涉及的内容方方面面,magento cache是基于zend的,如果你对zend cache理解很深的话,相信magento cache也不再话下,本篇文章着重介绍Flus ...
- 《JavaScript模式》第2章 基本技巧
@by Ruth92(转载请注明出处) 第2章 基本技巧 一.编写可维护的代码 阅读性好 具有一致性 预见性好 看起来如同一个人编写 有文档 编写注释 编写 API 文档 @namespace:用于命 ...
- Link Aggregation and LACP with Open vSwitch
In this post, I’m going to show you how to use link aggregation (via the Link Aggregation Control Pr ...
- Qt之QFileSystemWatcher
简述 QFileSystemWatcher类用于提供监视文件和目录修改的接口. QFileSystemWatcher通过监控指定路径的列表,监视文件系统中文件和目录的变更. 调用addPath()函数 ...
- 通过开发MSBuild ,引发的注册表相关知识
最近在做一个小项目,目的就是只需要点一个按钮,就把web程序发布到指定的服务器中.基本步骤就是 编译——>打包->复制包到远程服务器->解压缩.我想重点说一下解压缩,我们可以用win ...
- iOS学习笔记---c语言第八天
指针 首先将变量a的地址存放在另一个变量中,比如存放在变量b中,然后通过变量b来间接引用变量a,间接读写变量a的值.用来存放变量地址的变量,就称为"指针变量" int *p=nul ...
- ss命令使用示例
导读 ss是Socket Statistics的缩写,可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比n ...
- 浅谈C中的malloc和free
转自http://bbs.bccn.net/thread-82212-1-1.html非常感谢作者 浅谈C中的malloc和free 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的 ...
- 发布常见问题(C#)
1.Sys.WebForms.PageRequestManagerServerErrorException: 在服务器上处理请求时出现未知错误.服务器返回的状态码为: 500 可能的原因: asp.n ...
- c 函数及指针学习 7
1.结构的存储分配 1 2 printf("%d \n",sizeof(char)); printf("%d \n",sizeof(int)); int 类型为 ...