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. iOS-NSURLCache内存缓存

    在IOS应用程序开发中,为了减少与服务端的交互次数,加快用户的响应速度,一般都会在IOS设备中加一个缓存的机制.使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,是程序高效的运行.有时候我们需 ...

  2. Qt线程(1) moveToThread

    若在Qt准备使用线程类一般有两种方式(1) 采用WorkObject配合QThread进行使用 (2)继承QThread, 重载run()函数即可. 注:采用Qt::Concurrent之类的不在本文 ...

  3. 【题解】【BST】【Leetcode】Convert Sorted Array to Binary Search Tree

    Given an array where elements are sorted in ascending order, convert it to a height balanced BST.思路: ...

  4. PHP字符串——编码与转义

    因为PHP程序经常与HTML页.Web地址(URL)以及数据库交互,所以PHP提供一些函数来帮助你处理这些类型的数据.HTML.Web页地址和数据库命令都是字符串,但是它们每个都要求不同的字符以不同的 ...

  5. PostgreSQL增删数据命令示例

    在PostgreSQL中如何用简单的几条SQL语句生成大量的测试数据呢? 此处,我简单的写一个例子,供参考(在Postgresql9.1下面做的): (1)生成一万条测试数据的表foo mydb=# ...

  6. Context启动startActivity注意

    intent.setFlags()方法中参数的用例: 很多人使用startActivity时候,会碰到如下的异常:Caused by: android.util.AndroidRuntimeExcep ...

  7. Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)

    我们到底能走多远系列(33) 扯淡: 各位:    命运就算颠沛流离   命运就算曲折离奇   命运就算恐吓着你做人没趣味   别流泪 心酸 更不应舍弃   ... 主题: Spring源码阅读还在继 ...

  8. (基础篇)PHP流程控制语句

    不论是PHP还是别的语法,程序总是由若干条语句组成. 从执行方式上看,语句的控制结构分为以下三种: 1.  顺序结构:从第一条语句到最后一条语句完全顺序执行: 2.  选择结构:根据用户输入或语句的中 ...

  9. 开机流程与主引导分区(MBR)——鸟哥私房菜

    在前篇随笔中,已经谈到了CMOS与BIOS,CMOS是记录各项硬件参数(包括系统时间.设备的I/O地址.CPU的电压和频率等)且嵌入到主板上面的存储器,BIOS是一个写入到主板上的韧体(韧体是写入到硬 ...

  10. CSS基础知识点(一)

    CSS(Cascading Style Sheets)全称为:层叠样式表. 1.HTML元素类型 (1) 内联元素(inline):可以理解为“文本模式”,即从左到右顺序显示,不单独换行.常用的内联元 ...