phonegap

phonegap 框架详解

转自:http://www.cnblogs.com/hubcarl/p/4216844.html

首先, 来看一下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存储起来。

1
2
3
4
5
6
7
<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方法。
例如联系人管理插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:") 获取调用方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PhoneGap.Channel.join(function () {
    // Start listening for XHR callbacks
    setTimeout(function () {
      if (PhoneGap.UsePolling) {
        PhoneGap.JSCallbackPolling();
      }
      else {
        console.log('PhoneGap.Channel.join>>>>>>>>>>>>>>>>>>>>>>>>>');<br>       <span style="color: #ff6600;"//phonegap js 首次启动获取js调用Native方式</span>
        var polling = prompt("usePolling""gap_callbackServer:");
        PhoneGap.UsePolling = polling;
        if (polling == "true") {
          PhoneGap.UsePolling = true;
          <span style="color: #ff6600;">PhoneGap.JSCallbackPolling();</span>
        }
        else {
          PhoneGap.UsePolling = false;
         <span style="color: #ff6600;"> PhoneGap.JSCallback();</span>
        }
      }
    }, 1);
}

  

XHR轮询:PhoneGap.JSCallback方法

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (PhoneGap.JSCallbackPort === null) {
   PhoneGap.JSCallbackPort = <span style="color: #ff6600;">prompt("getPort""gap_callbackServer:");</span>
   console.log('PhoneGap.JSCallback getPort>>>>>>>>>>>>>>>>>>>>>>>>>:' + PhoneGap.JSCallbackPort);
}
if (PhoneGap.JSCallbackToken === null) {
  PhoneGap.JSCallbackToken =<span style="color: #ff6600;"> prompt("getToken""gap_callbackServer:");</span>
  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);
 <span style="color: #ff6600;">setTimeout(PhoneGap.JSCallback, 1);</span><br>}

  

prompt轮询: PhoneGap.JSCallbackPolling方法

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<span style="color: #ff6600;">PhoneGap.JSCallbackPolling</span> = 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);
      <span style="color: #ff6600;">setTimeout(PhoneGap.JSCallbackPolling, 1);</span>
    }
    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

转载于:https://www.cnblogs.com/iverson-weng/p/5098582.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

j2ee核心模式_Operator和Sidecar正在成为软件交付新模式

现如今的开发人员希望可以开发出具备弹性和可扩展的分布式系统。该系统受益于软件复用和开源模型创新&#xff0c;针对安全性问题能够轻易完成补丁更新并进行低风险的升级。该系统不可能通过带有各种嵌入式语言库的应用程序框架来实现。最近&#xff0c;一篇关于“多运行时微服…

微信JS-SDK选择相册或拍照并上传PHP实现

理解&#xff1a;微信上传接口是拍照&#xff0c;或者选择本地照片&#xff0c;上传到微信的服务器&#xff0c;获取到一个id&#xff0c;通过token与这个id获取到图片&#xff0c;保存到服务器即可。 效果 通过微信js接口&#xff0c;调用底层程序。 需要引入js文件&#xff0…

android socket 长连接_TCP/IP,http,socket,长连接,短连接

点击上方蓝色字体&#xff0c;选择“标星公众号”优质文章&#xff0c;第一时间送达上一篇&#xff1a;这300G的Java资料是我师傅当年给我的&#xff0c;免费分享给大家下一篇&#xff1a;这200G的Java实战资料是我师傅当年教我的第二招作者 | ksfzhaohui来源 | my.oschina.net…

二、Python安装扩展库

第一步:推荐easy_install工具 下载地址:https://pypi.python.org/pypi/setuptools 下载"ez_setup.py"文件; 通过运行cmd命令找到ez_setup.py文件所在目录,通过命令[python ez_setup.py]执行安装easy_install 安装成功截图 第二步:安装扩展酷 例如安装"suds"…

ORACLE 10.2.01升级10.2.05 for windows 详细文档

最近要做一个数据库的升级工作&#xff0c;提前在自己的PC机上练习了一下&#xff0c;这种文档在网上很多&#xff0c;但是大多都是使用命令编辑脚本&#xff0c;其实数据库还有一个DBUA的升级工具可以使用&#xff0c;使升级工作方便了很多。 OS环境&#xff1a;windows XP 32…

stm32正交编码器 原理图_恶劣环境下应用的电感式增量编码器和绝对编码器

编码器可分为两种基本类型 - 增量编码器和绝对编码器。增量编码器的显着特征是它报告角度的变化。换句话说&#xff0c;当增量编码器通电时&#xff0c;它不会报告其角位置&#xff0c;直到它具有测量的参考点。绝对编码器明确地在比例或范围内报告其位置。换句话说&#xff0c…

python基础代码的含义_Python基础学习篇

原标题&#xff1a;Python基础学习篇 1、编码 默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&#xff0c;所有字符串都是unicode 字符串。 当然你也可以为源码文件指定不同的编码&#xff1a;# -*- coding: cp-1252 -*- 2、标识符 第一个字符必须是字母表中字母或下划…

java面向对象super_【JavaSE】面向对象之super、final

一、super关键字它是一个指代变量&#xff0c;用于在子类中指代父类对象。1.作用指代父类对象区分子父类同名的成员变量&#xff0c;区分父类中成员变量和子类中同名的局部变量2.使用与this相同&#xff0c;调用父类成员变量和成员方法&#xff1a;super.xx super.xxx()调用父类…

mac下的svn服务器建立

MAC下的SVN服务器建立: from : http://blog.csdn.net/q199109106q/article/details/8655204 在Windows环境中&#xff0c;我们一般使用TortoiseSVN来搭建svn环境。在Mac环境下&#xff0c;由于Mac自带了svn的服务器端和客户端功能&#xff0c;所以我们可以在不装任何第三方软件…

php 字符串 替换 最后,php如何替换字符串中的最后一个字符

php替换字符串中的最后一个字符的方法是&#xff1a;可以通过preg_replace()函数来实现。该函数的语法为&#xff1a;【preg_replace(mixed $pattern, mixed $replacement, mixed $subject】。要替换字符串中的最后一个字符&#xff0c;可以通过preg_replace()函数来实现。(如果…

logback的使用和logback.xml详解

原文地址&#xff1a;https://www.cnblogs.com/warking/p/5710303.html#4046335 作者&#xff1a;行走在云端的愚公 一、logback的介绍   Logback是由log4j创始人设计的另一个开源日志组件,官方网站&#xff1a; http://logback.qos.ch。它当前分为下面下个模块&#xff1a; …

tcp协议的主要功能是什么_前端要知道的网络知识一:TCP/IP 协议到底在讲什么...

你之所以不知道那套书在讲什么&#xff0c;是因为你还没有认识到网络协议有什么用&#xff0c;怎么用&#xff0c;以什么形式在使用&#xff0c;网络协议的概念很简单&#xff0c;就几句话&#xff0c;你只知道网络协议的概念&#xff0c;只知道很多大神都推荐这套书&#xff0…

mysql创建定时器(event),查看定时器,打开定时器,设置定时器时间

为什么80%的码农都做不了架构师&#xff1f;>>> 由于项目需要创建定时器&#xff08;evevt&#xff09;&#xff0c;所以就百度了一下&#xff0c;发现基本都是来源于一个模板&#xff0c;有些功能还不全&#xff0c;现在自己总结一下。 注&#xff1a;mysql版本是…

音频视频

1.IOS视频播放代码&#xff08;添加MediaPlayer.framework和#import&#xff09; -(void)playMovie:(NSString *)fileName{//视频文件路径NSString *path [[NSBundle mainBundle] pathForResource:fileName ofType:"mp4"];//视频URLNSURL *url [NSURL fileURLWithP…

linux内核怎么修改屏幕旋转方向_树莓派4—屏幕旋转

配置&#xff1a;树莓派4raspberry pi系统&#xff0c;HDMI显示&#xff0c;非触屏。问题&#xff1a;想将屏幕旋转90&#xff0c;按网上说的&#xff0c;方法一&#xff1a;在config.txt文件中添加display_rotate1&#xff0c;或者添加display_hdmi_rotate1&#xff0c;保存后…

独家直播!阿里移动前端开源框架Weex揭秘

或许你写过了很多行代码&#xff0c;修过许多的bug&#xff0c;学过各种各样的语言&#xff0c;却只在一个最好的时机遇见了他…… 是啥&#xff1f; 敲&#xff01;黑&#xff01;板&#xff01;跟&#xff01;我&#xff01;念&#xff01;Weex&#xff5e;&#xff5e;&…

python异常值处理实例_利用Python进行异常值分析实例代码

前言 异常值是指样本中的个别值&#xff0c;也称为离群点&#xff0c;其数值明显偏离其余的观测值。常用检测方法3σ原则和箱型图。其中&#xff0c;3σ原则只适用服从正态分布的数据。在3σ原则下&#xff0c;异常值被定义为观察值和平均值的偏差超过3倍标准差的值。P(|x−μ|…

MSSQL 发布订阅,实现读写分离

主库做增删改&#xff0c;从库只读。 大部分的数据库压力&#xff0c;都是由查询引起的&#xff0c;读写分离可以减轻数据库的压力。 1、在(主)数据库上对需要同步的数据进行发布。 2、在(从)数据库上对(主)数据库的发布进行订阅。 注&#xff1a;发布订阅都需要实际的服务器名…

Block

1、认识Block Block封装了一段代码,可以在任何时候执行Block可以作为函数参数或者函数的返回值&#xff0c;而其本身又可以带输入参数或返回值&#xff0c;它和传统的函数指针很类似&#xff0c;但是有区别&#xff1a;block是inline&#xff08;内联函数&#xff09;的&#x…

坚持学习WF(8):本地服务之调用外部方法

WF提供了一组核心服务&#xff0c;例如在SQL 数据库中存储工作流实例的执行详细信息的持久性服务&#xff0c;计划服务&#xff0c;事务服务和跟踪服务。除了这些WF也提供了另外一种服务&#xff0c;叫做Local Service也可以叫做Data exchange service。主要是实现工作流和宿主…