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.pswp.cn/news/396998.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396998.shtml
英文地址,請注明出處:http://en.pswp.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…

JMS-ActiveMQ學習-3 ActiveMQ與Spring集成

Spring下開發消息的發送和接收程序 點對點模式 一、創建生產者項目 1.創建maven項目 2.添加spring-jms、jms規范、activemq依賴 <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms&…

看libevent所遇到的英語生詞

libevent – an event notification library The libevent API &#xff08;libevent應用程序&#xff09;provides a mechanism&#xff08;機制&#xff09; to execute&#xff08;執行&#xff09; a callback function&#xff08;回調函數&#xff09; when a specific&a…

java中迭代器要導包嗎_java 中迭代器的使用方法詳解

java 中迭代器的使用方法詳解前言&#xff1a;迭代器模式將一個集合給封裝起來&#xff0c;主要是為用戶提供了一種遍歷其內部元素的方式。迭代器模式有兩個優點&#xff1a;①提供給用戶一個遍歷的方式&#xff0c;而沒有暴露其內部實現細節&#xff1b;②把元素之間游走的責任…

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…

php 導出mysql 結構_導出結構和數據(如phpmyadmin)

在這里,您可以找到一個全面的解決方案來轉儲MySQL結構和數據,比如在PMA中(不使用exec、passthru等):它是Dszymczuk項目的一個分支,有我的增強功能。用法很簡單//MySQL connection parameters$dbhost localhost;$dbuser dbuser;$dbpsw pass;$dbname dbname;//Connects to my…

tableViewCell的操作

在iOS的開發過程中&#xff0c;tableView的使用永遠都是最常用的控件。今天學習了一下tableViewCell的操作。代碼并不是很復雜&#xff0c;如果有OC開發經驗的人&#xff0c;應該很容易看懂的。 class ViewController: UIViewController ,UITableViewDelegate, UITableViewData…

stm32正交編碼器 原理圖_惡劣環境下應用的電感式增量編碼器和絕對編碼器

編碼器可分為兩種基本類型 - 增量編碼器和絕對編碼器。增量編碼器的顯著特征是它報告角度的變化。換句話說&#xff0c;當增量編碼器通電時&#xff0c;它不會報告其角位置&#xff0c;直到它具有測量的參考點。絕對編碼器明確地在比例或范圍內報告其位置。換句話說&#xff0c…

【SqlServer】Sqlserver中的DOS命令操作

輸入osql ?查看是否支持當前版本&#xff0c;如果是SQL Server 2005以上用Sqlcmd , 以下用Osql連接數據庫&#xff08;a&#xff09;Osql -S localhost -U username -P password(SQL Server身份驗證&#xff0c;需要用戶民和密碼)&#xff08;b&#xff09;Osql -S localhos…

微信小程序內訓筆記

2016年9月22日凌晨微信官方正式宣布“小程序”開始內測&#xff0c;有“微信之父”之稱、騰訊集團高級執行副總裁張小龍在2016年末對外宣布“小程序“應用將于2017年1月9日正式推出 這一次微信還是按照慣例&#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()調用父類…

Week_1_Physical Electronics and Semiconductors

Semiconductors Fundamentals Type of solids 轉載于:https://www.cnblogs.com/ronnielee/p/9579783.html

【Linux高頻命令專題(23)】tar

概述 通過SSH訪問服務器&#xff0c;難免會要用到壓縮&#xff0c;解壓縮&#xff0c;打包&#xff0c;解包等&#xff0c;這時候tar命令就是是必不可少的一個功能強大的工具。linux中最流行的tar是麻雀雖小&#xff0c;五臟俱全&#xff0c;功能強大。 tar命令可以為linux的文…

2. Add Two Numbers

直接用一個carry記錄進位就可以 1 //NEW2 class Solution {3 public ListNode addTwoNumbers(ListNode l1, ListNode l2) {4 ListNode root new ListNode(0);5 return addTwoNumbers(l1, l2, root);6 }7 public ListNode addTwoNumbers(ListNode …

安裝Windows更新程序遇到錯誤:0x80070422

看看服務那里 windows update服務是不是被禁用了&#xff1f; 還有一個問題可能是由于Windows Modules Installer被禁用了。

談談對python的理解_淺談對python pandas中 inplace 參數的理解

這篇文章主要介紹了對python pandas中 inplace 參數的理解&#xff0c;具有很好的參考價值&#xff0c;希望對大家有所幫助。一起跟隨小編過來看看吧 pandas 中 inplace 參數在很多函數中都會有&#xff0c;它的作用是&#xff1a;是否在原對象基礎上進行修改 inplace True&am…