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主页

http://phonegap.com/

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原理分析的更多相关文章

  1. HTML5 移动应用开发环境搭建及原理分析

    开发环境搭建: 一.Android 开发平台搭建 安装java jdk:\\10.194.151.132\Mewfile\tmp\ADT 配置java jdk 1)  新建系统变量,JAVA_HOME ...

  2. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  3. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  4. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  5. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  6. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  7. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  8. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  9. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

随机推荐

  1. magento缓存系列详解:clean cache

    cache是一个很大的概念,涉及的内容方方面面,magento cache是基于zend的,如果你对zend cache理解很深的话,相信magento cache也不再话下,本篇文章着重介绍Flus ...

  2. 《JavaScript模式》第2章 基本技巧

    @by Ruth92(转载请注明出处) 第2章 基本技巧 一.编写可维护的代码 阅读性好 具有一致性 预见性好 看起来如同一个人编写 有文档 编写注释 编写 API 文档 @namespace:用于命 ...

  3. 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 ...

  4. Qt之QFileSystemWatcher

    简述 QFileSystemWatcher类用于提供监视文件和目录修改的接口. QFileSystemWatcher通过监控指定路径的列表,监视文件系统中文件和目录的变更. 调用addPath()函数 ...

  5. 通过开发MSBuild ,引发的注册表相关知识

    最近在做一个小项目,目的就是只需要点一个按钮,就把web程序发布到指定的服务器中.基本步骤就是 编译——>打包->复制包到远程服务器->解压缩.我想重点说一下解压缩,我们可以用win ...

  6. iOS学习笔记---c语言第八天

    指针 首先将变量a的地址存放在另一个变量中,比如存放在变量b中,然后通过变量b来间接引用变量a,间接读写变量a的值.用来存放变量地址的变量,就称为"指针变量" int *p=nul ...

  7. ss命令使用示例

    导读 ss是Socket Statistics的缩写,可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比n ...

  8. 浅谈C中的malloc和free

    转自http://bbs.bccn.net/thread-82212-1-1.html非常感谢作者 浅谈C中的malloc和free 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的 ...

  9. 发布常见问题(C#)

    1.Sys.WebForms.PageRequestManagerServerErrorException: 在服务器上处理请求时出现未知错误.服务器返回的状态码为: 500 可能的原因: asp.n ...

  10. c 函数及指针学习 7

    1.结构的存储分配 1 2 printf("%d \n",sizeof(char)); printf("%d \n",sizeof(int)); int 类型为 ...