首先, 来看一下phonegap 初始化流程以及Native 与 JS 交互流程图。

说明:socket server模式下, phonegap.js 源码实现的采用1 毫秒执行一次XHR请求,  当Native  JS 队列里面有JS语句数据时,才是真正的1毫秒调用一下;  当没有数据, scoket server 会阻塞10毫秒, 也就是XHR 要等10秒钟才能收到结果,并进行下一次的轮询。

1、Activity继承 DroidGap (extends PhonegapActivity)

从phonegap.xml 中加载白名单配置 和 log配置

2、loadUrl (每个Activity 都初始化一次)

》》初始化webview
》》初始化callbackServer
》》插件管理器PluginManager

3、加载插件配置:

》》读取 plugins.xml 配置,用map存储起来。

<plugins>
<plugin name="Camera" value="com.phonegap.CameraLauncher"/>
<plugin name="Contacts" value="com.phonegap.ContactManager"/>
<plugin name="Crypto" value="com.phonegap.CryptoHandler"/>
<plugin name="File" value="com.phonegap.FileUtils"/>
<plugin name="Network Status" value="com.phonegap.NetworkManager"/>
</plugins>

说明:
name 是别名,javascript调用时通过别名来调用。
value:java具体实现类

web页面调用(例如查找联想人)
PhoneGap.exec(successCB, errorCB, "Contacts", "search", [fields, options]);

4、插件实现

》》编程java类,继承Plugin类(Plugin 实现了IPlugin接口),并实现execute方法。
例如联系人管理插件:

public class ContactManager extends Plugin{
/**
* action : 用来指定一个具体动作 search 表示搜索联系人
* args: 方法参数
* callbackId:js与java指定一个标识,
*/
public PluginResult execute(String action, JSONArray args, String callbackId) {
try {
if (action.equals("search")) {
JSONArray res = contactAccessor.search(args.getJSONArray(0), args.optJSONObject(1));
return new PluginResult(status, res, "navigator.contacts.cast");
}
else if (action.equals("save")) {
String id = contactAccessor.save(args.getJSONObject(0));
if (id != null) {
JSONObject res = contactAccessor.getContactById(id);
if (res != null) {
return new PluginResult(status, res);
}
}
}
else if (action.equals("remove")) {
if (contactAccessor.remove(args.getString(0))) {
return new PluginResult(status, result);
}
}
// If we get to this point an error has occurred
JSONObject r = new JSONObject();
r.put("code", UNKNOWN_ERROR);
return new PluginResult(PluginResult.Status.ERROR, r);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
}
}

  

5、polling和server初始化

android DroidGap 初始化时,如果loadUrl的url不是以file:// 开头时,polling = true, 否则是socket server方式

代码见CallbackServer.java 类init方法

public void init(String url) {
//System.out.println("CallbackServer.start("+url+")");
// Determine if XHR or polling is to be used
if ((url != null) && !url.startsWith("file://")) {
this.usePolling = true;
this.stopServer();
}
else if (android.net.Proxy.getDefaultHost() != null) {
this.usePolling = true;
this.stopServer();
}
else {
this.usePolling = false;
this.startServer();
}
}

  

6、phonegap.js  关键代码说明

phonegap.js在启动时,首先会通过prompt("usePolling", "gap_callbackServer:")获取调用方式: XHR 轮询 OR prompt 轮询,  如果是XHR的话, 会启动XHR调用获取http server端口 和token。

方法PhoneGap.Channel.join 启动 js server 或者polling调用 

UsePolling 默认为false。 通过var polling = prompt("usePolling", "gap_callbackServer:") 获取调用方式。

 PhoneGap.Channel.join(function () {

    // Start listening for XHR callbacks
setTimeout(function () {
if (PhoneGap.UsePolling) {
PhoneGap.JSCallbackPolling();
}
else {
console.log('PhoneGap.Channel.join>>>>>>>>>>>>>>>>>>>>>>>>>');
//phonegap js 首次启动获取js调用Native方式
var polling = prompt("usePolling", "gap_callbackServer:");
PhoneGap.UsePolling = polling;
if (polling == "true") {
PhoneGap.UsePolling = true;
PhoneGap.JSCallbackPolling();
}
else {
PhoneGap.UsePolling = false;
PhoneGap.JSCallback();
}
}
}, 1);
}

  

XHR轮询:PhoneGap.JSCallback方法

通过XHR 与java端 socket进行通信,每一毫秒执行一次JSCallback,从android socket获取javascript执行结果代码,最后通过eval动态执行javascript

XHR调用, 通过prompt 获取socket端口 和 token(uuid)

if (PhoneGap.JSCallbackPort === null) {
PhoneGap.JSCallbackPort = prompt("getPort", "gap_callbackServer:");
console.log('PhoneGap.JSCallback getPort>>>>>>>>>>>>>>>>>>>>>>>>>:' + PhoneGap.JSCallbackPort);
}
if (PhoneGap.JSCallbackToken === null) {
  PhoneGap.JSCallbackToken = prompt("getToken", "gap_callbackServer:");
  console.log('PhoneGap.JSCallback getToken>>>>>>>>>>>>>>>>>>>>>>>>>:' + PhoneGap.JSCallbackToken);
}
xmlhttp.open("GET", "http://127.0.0.1:" + PhoneGap.JSCallbackPort + "/" + PhoneGap.JSCallbackToken, true);
xmlhttp.send(); XHR返回结果代码片段
var msg = decodeURIComponent(xmlhttp.responseText);
setTimeout(function () {
try {
var t = eval(msg);
}
catch (e) {
// If we're getting an error here, seeing the message will help in debugging
console.log("JSCallback: Message from Server: " + msg);
console.log("JSCallback Error: " + e);
}
}, 1);
setTimeout(PhoneGap.JSCallback, 1);
}

  

prompt轮询: PhoneGap.JSCallbackPolling方法

PhoneGap.JSCallbackPolling = function () {

    // Exit if shutting down app
if (PhoneGap.shuttingDown) {
return;
} // If polling flag was changed, stop using polling from now on
if (!PhoneGap.UsePolling) {
PhoneGap.JSCallback();
return;
} var msg = prompt("", "gap_poll:");
if (msg) {
setTimeout(function () {
try {
var t = eval("" + 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);
}
};

  

 7、总结

  1、phonegap android 插件管理器PluginManager初始化时, 是每个Activity都要初始化一次, 数据都缓存一次, 导致同一份数据缓存多次。-- 暂不清楚为啥这样实现? 难道是phonegap 框架是为单webview 实现的,如果有知道原因的请告知一下。

2、同第1点一样, Socket Server 每个Activity都会初始化一下, 如果loadUrl 的url类型不同,会不会导致scoket server状体错乱, 待验证!

3、phonegap 采用 prompt 和 XHR 轮询机制,一是会导致手机耗电情况严重, 二是了解到prompt 调用是会阻塞js执行的, 这样导致影响到页面加载速度。

phonegap 已经改名cordova, 在最新版本cordova 框架里面已经去掉了socket server模式, 详细请查看:http://www.cnblogs.com/hubcarl/p/4202784.html

phonegap 框架详解的更多相关文章

  1. jQuery Validate验证框架详解

    转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...

  2. mina框架详解

     转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...

  3. lombok+slf4j+logback SLF4J和Logback日志框架详解

    maven 包依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb ...

  4. [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解

    Core data 是 Cocoa 中处理数据,绑定数据的关键特性,其重要性不言而喻,但也比较复杂.Core Data 相关的类比较多,初学者往往不太容易弄懂.计划用三个教程来讲解这一部分: 框架详解 ...

  5. iOS 开发之照片框架详解(2)

    一. 概况 本文接着 iOS 开发之照片框架详解,侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLib ...

  6. (转)phonegap 数据库详解

    原文:http://firepix.iteye.com/blog/1618343 phonegap 数据库详解          博客分类: web App phonegap  今天就把之前使用pho ...

  7. Quartz.NET作业调度框架详解

    Quartz.NET作业调度框架详解 http://www.cnblogs.com/lmule/archive/2010/08/28/1811042.html

  8. mapreduce框架详解

    hadoop 学习笔记:mapreduce框架详解 开始聊mapreduce,mapreduce是hadoop的计算框架,我学hadoop是从hive开始入手,再到hdfs,当我学习hdfs时候,就感 ...

  9. iOS 开发之照片框架详解之二 —— PhotoKit 详解(下)

    本文链接:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-three.html 这里接着前文<iOS ...

随机推荐

  1. 异步加载JS的4种方式(详解)

    方案1:$(document).ready <!DOCTYPE html> <html> <head> <script src="http://co ...

  2. zigbee学习之路(六):Time3(查询方式)

    一.前言 通过上次的学习,相信大家对cc2530单片机的定时器的使用有了一定的了解,今天我们来介绍定时器3的使用,为什么介绍定时器3呢,因为它和定时器4功能是差不多的,所以学会定时器3,就基本掌握了c ...

  3. Android中Bitmap和Drawable

    一.相关概念 1.Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),还有可能是一个图层(LayerDrawable) ...

  4. VS2013: upgrading a Windows Phone 7/8 and Windows 8 apps(转)

    VS2013: upgrading a Windows Phone 7/8 and Windows 8 apps September 17, 2013Windows 8, Windows PhoneJ ...

  5. 遗传算法在JobShop中的应用研究(part1: 绪论)

    1. 什么是JobShop问题 Job,中文翻译成工件.一个工件又由若干道工序加工完成. resource, 资源.在本文的车间调度中资源指的是机器,每道工序要在某个特定机器上加工. Constrai ...

  6. python pip install

    wget --no-check-certificate https://github.com/pypa/pip/archive/1.5.5.tar.gz https://github.com/pypa ...

  7. 深入浅出设计模式——工厂方法模式(Factory Method)

    介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...

  8. 数据库 基础篇2(mysql)

    2.1MySQL入门 1)到mysql官网下载. 2)安装mysql软件 3)使用 验证是否成功 打开cmd  -> 输入 mysql -u root -p  回车   -> 输入密码   ...

  9. vue.js学习笔记之v-bind,v-on

    v-bind 指令用于响应地更新 HTML 特性 形式如:v-bind:href    缩写为    :href; v-on 指令用于监听DOM事件 形式如:v-on:click  缩写为 @clic ...

  10. Xcode 8 的 Debug 新特性

    Contents OverView Static Analyzer Localizability Instance Cleanup Nullablility Runtime Issue View De ...