引言 Cordova(PhoneGap)採用的是HTML5+JavaScript混合模式來開發移動手機APP,因此當頁面需要獲取手機內部某些信息時(例如:聯繫人信息,坐標定位,簡訊等),程式就需要調用手機內部的API跟頁面進行信息交換。Cordova 特別為此定製了完善的解決方案,以方便用戶進行程式 ...
Cordova(PhoneGap)採用的是HTML5+JavaScript混合模式來開發移動手機APP,因此當頁面需要獲取手機內部某些信息時(例如:聯繫人信息,坐標定位,簡訊等),程式就需要調用手機內部的API跟頁面進行信息交換。Cordova 特別為此定製了完善的解決方案,以方便用戶進行程式編輯。在這一章里將為大家逐一介紹Cordova與Actitity通訊的實現原理。
目錄
二、頁面通過 cordova.exec 函數調用 CordovaPlugin 插件
四、頁面通過CordovaPlugin插件調用Activity開發實例
一、CordovaPlugin類簡介
CordovaPlugin是Cordova插件的父類,用戶自定義的插件必須繼承父類,它的主要常用屬性如下
屬性 | 詳細說明 |
CordovaWebView | 視圖管理器,當中包括PluginManager、CordovaWebViewEngine、ICordovaCookieManager等多個對象,用於管理界面渲染,視圖載入過程中的生命周期 |
CordovaInterface | 定義startActivityForResult、setActivityResultCallback等主要方法,獲取調用上下文中的Activity對象 |
CordovaPreferences | 用於管理bundle中的屬性值 |
表格1.1
CordovaPlugin的常用方法如下
方法 | 詳細說明 |
void privateInitialize(String serviceName, CordovaInterface cordova, CordovaWebView webView, CordovaPreferences preferences) | 插件初始化時執行,用於定義service名稱,cordovaInterface介面,CodovaWebView視圖,CordovaPreferences 屬性等值 |
boolean execute(String action, String rawArgs, CallbackContext callbackContext) | 在開發插件時,用戶的自定義方法,當頁面調用插件時系統首先將會運行此方法 |
boolean execute(String action, JSONArray args, CallbackContext callbackContext) | 同上 |
boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) | 同上 |
void onActivityResult(int requestCode, int resultCode, Intent intent) | 在開發插件時,用戶的自定義方法,插件調用startActivityForResult後的回調函數。 |
String getServiceName() | 獲取在config文件中該服務的名稱 |
Boolean shouldAllowRequest(String url) | 判斷是否允許此請求 |
Boolean shouldAllowNavigation(String url) | 判斷是否允許此導航 |
Boolean shouldOpenExternalUrl(String url) | 判斷是否打開外部鏈接 |
boolean onReceivedHttpAuthRequest(CordovaWebView view, ICordovaHttpAuthHandler handler, String host, String realm) | |
boolean onReceivedClientCertRequest(CordovaWebView view, ICordovaClientCertRequest request) |
表格1.2
CordovaPlugin的詳細解析可參考官網
二、頁面調用 CordovaPlugin 插件實例
大概瞭解 CordovaPlugin 類的使用方法後,下麵為大家介紹一下頁面調用插件的例子。首先打開文件res/xml/config.xml為插件進行配置。
<preference/>可用於運行環境中的常用參數,例如:全屏設置,滾動條設置,背景色設置等等
<preference name="Fullscreen" value="true" />
<preference name="DisallowOverscroll" value="true"/>
<preference name="BackgroundColor" value="0xff0000ff"/>
<feature></feature>節點用於設置插件描述,feature的name屬性是設置插件的唯一標示,在頁面調用插件時將通過name找到此插件
在開發插件時,先為此插件添加一個<feature>節點,在<param>中綁定插件的後臺執行文件ShowMessagePlugin.java
<param name="android-package" value="org.apache.cordova.showmessage.ShowMessagePlugin" />
1 <?xml version='1.0' encoding='utf-8'?> 2 <widget id="com.sun.androidapp" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> 3 <!--設置運行環境中的參數值 --> 4 <preference name="loglevel" value="DEBUG" /> 5 <!-- 插件描述 --> 6 <feature name="Whitelist"> 7 <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" /> 8 <param name="onload" value="true" /> 9 </feature> 10 <feature name="ShowMessage"> 11 <param name="android-package" value="org.apache.cordova.showmessage.ShowMessagePlugin" /> 12 </feature> 13 <allow-intent href="market:*" /> 14 <!-- 該APP名稱 --> 15 <name>AndroidTest</name> 16 <!-- APP描述 --> 17 <description> 18 A sample Apache Cordova application that responds to the deviceready event. 19 </description> 20 <!-- 作者信息描述 --> 21 <author email="[email protected]" href="http://cordova.io"> 22 Apache Cordova Team 23 </author> 24 <!-- 預設啟動頁面 --> 25 <content src="index.html" /> 26 <!-- 指定app可進行通信的功能變數名稱,*為所有 --> 27 <access origin="*" /> 28 <!-- App預設只請允許通過手機端直接打開,若想通過網站,SMS等方式調用APP,則需要設置allow-intent配置 --> 29 <allow-intent href="http://*/*" /> 30 <allow-intent href="https://*/*" /> 31 <allow-intent href="tel:*" /> 32 <allow-intent href="sms:*" /> 33 <allow-intent href="mailto:*" /> 34 <allow-intent href="geo:*" /> 35 </widget>
建立org.apache.cordova.showmessage.ShowMessagePlugin類,且繼承CordovaPlugin基類,並實現
bool execute(action,args,callbackcontext) 方法。當頁面調用此插件時,預設執行此方法。
action 是唯一標識符,系統可根據不同的action進行不同的操作。
args是頁面傳入的參數,支持String, JsonArray,CordovaArgs 等三種不同的類型。
callbackcontext是系統的上下文,當完成操作後調用callbackcontext.success(支持多類型參數)方法,表示插件操作已完成,並把參數返還到頁面。最終返回true代表插件執行成功,false代表執行失敗
1 package org.apache.cordova.showmessage; 2 3 public class ShowMessagePlugin extends CordovaPlugin { 4 @Override 5 public boolean execute(String action,JSONArray args,CallbackContext context) 6 throws JSONException{ 7 if(action.equals("mydream")){ 8 String msg=args.getString(0)+"'s dream is to become a "+args.getString(1); 9 context.success(msg); 10 return true; 11 } 12 return false; 13 } 14 }
在 cordova.js 包中,最常用的是 cordova.exec(success,failed,service,action,args)函數,頁面正是通過此函數調用插件。
success 用於綁定插件執行成功後回調的回調函數
failed用於綁定執行失敗的回調函數
service與config.xml配置文件中feature位元組的name屬性相對應
action與ShowMessagePlugin對象boolean excute方法中action參數對應,用於分辨插件執行的方法類型,插件可根據action類型的不同作出分類處理。
args為輸入參數
1 Name: <input type="text" id="txt1"/> 2 Dream:<input type="text" id="txt2"/> 3 <input type="button" onclick="btnclick()" name="btn" value="Click"/> <br/> 4 <label id="label"></label> 5 6 <script type="text/javascript"> 7 8 function btnclick(){ 9 var name=$("#txt1").val(); 10 var dream=$("#txt2").val(); 11 //通過 cordova.exec (success,failed,serviceName,action,args)函數調用插件 12 cordova.exec(success,failed,"ShowMessage","mydream",[name,dream]) 13 } 14 15 //成功調用插件,獲取返回值後的頁面處理函數 16 function success(result){ 17 if(result!=null) 18 $("#label").html(result); 19 else 20 alert("no message"); 21 } 22 23 //調用失敗後的處理函數 24 function failed(msg){ 25 ...... 26 } 27 </script>
測試結果
三、CordovaInterface介面說明
CordovaInterface 介面預設是由 CordovaInterfaceImpl 類實現的,當中包括了一個Activity對象。當打開APP時 Cordova 會預設啟動此 Activity 以承載 Cordova 核心引擎對程式進行管理。ExecutorService 則負責對象對線程池進行管理,PluginManager則負責對插件進行管理,CordovaPlugin則是Cordova插件的父類,所有插件都必須繼承CordovaPlugin。
屬性 | 詳細說明 |
Activity | 打開APP時 Cordova 會預設啟動此 Activity 以承載 Cordova 核心引擎對程式進行管理 |
ExecutorService | 對線程池進行管理 |
PluginManager | 插件管理器,用於管理插件的生成,運行,結束等生命周期 |
CordovaPlugin | 通過startActivityForResult方法綁定CordovaPlugin插件 |
ActivityResultHolder | 內部類,封裝了requestCode, resultCode, intent等對象 |
表格2.1
CordovaInterfaceImpl定義了三個最常用方法
方法 | 詳細說明 |
void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) | 綁定CordovaPlugin參數,並調用Activity對象的startActivityForResult(intent, requestCode)方法,根據 intent 綁定值跳轉到對應的activity |
void setActivityResultCallback(CordovaPlugin plugin) | 激發CordovaPlugin對象的onActivityResult事件 |
boolean onActivityResult(int requestCode, int resultCode, Intent intent) | 封裝Acticity對象的onActivityResult回調函數, 激發CordovaPlugin對象的onActivityResult事件 |
表格2.2
四、頁面通過CordovaPlugin插件調用Activity開發實例
類似於第一節實例,在頁面通過cordova.exec(success,failed,service,action,args)方法調用插件,返回時調用success函數進行處理顯示結果
1 出游省份: 2 <select id="select1"> 3 <option value='1' selected='selected'>黑龍江</option> 4 <option value='2'>吉林</option> 5 <option value='3'>遼寧</option> 6 </select> 7 <input type="button" onclick="btnclick()" name="btn" value="查找"/> <br/> 8 路線景點: 9 <label id="label"></label><br/> 10 11 <script type="text/javascript"> 12 13 function btnclick(){ 14 var province=$("#select1").val(); 15 //通過 cordova.exec (success,failed,serviceName,actionName,args)函數調用插件 16 cordova.exec(success,null,"ShowMessage","showMessage",[province]); 17 } 18 19 //成功調用插件,獲取返回值後的頁面處理函數 20 function success(result){ 21 if(result!=null) 22 $("#label").html(result); 23 else 24 alert("no message"); 25 } 26 </script>
插件通過判斷action參數判斷進行不同的處理,然後通過Intent對象綁定將要啟動的Activity,最後通過CordovaInterface中的startActivityForResult(cordovaPlugin,intent,int)方法啟動該Activity。當 Activity 結束後,系統將調用回調函數 onActivityResult(int requestCode, int resultCode, Intent intent)
在此說明一下Intent類的用途,此類主要用於綁定當前的活動與子活動之間關係,當中包含6種構造函數。
1、Intent() 空構造函數
2、Intent(Intent o) 拷貝構造函數
3、Intent(String action) 指定action類型的構造函數
4、Intent(String action, Uri uri) 指定Action類型和Uri的構造函數,URI主要是結合程式之間的數據共用ContentProvider
5、Intent(Context packageContext, Class<?> cls) 傳入組件的構造函數,也就是此例子中使用到的
6、Intent(String action, Uri uri, Context packageContext, Class<?> cls) 前兩種結合體
Intent 類中封裝了一個Bundle 對象 mExtras,可用於主活動與子活動之間傳值,系統可通過 putExtra 方法把參數傳入mExtras, 也可通過 getShortExtra、getIntExtra、getBooleanExtra、getByteExtra 等多個方法從mExtras 獲取參數值。
1 public class ShowMessagePlugin extends CordovaPlugin { 2 private CallbackContext context; 3 4 @Override 5 public boolean execute(String action,JSONArray args,CallbackContext context) 6 throws JSONException{ 7 this.context=context; 8 //根據action判斷調用方法 9 if(action.equals("showMessage")){ 10 //通過Intent綁定將要調用的Activity 11 Intent intent=new Intent(this.cordova.getActivity(),SpotActivity.class); 12 //加入將要傳輸到activity中的參數 13 intent.putExtra("province", args.getString(0)); 14 //啟動activity 15 this.cordova.startActivityForResult(this, intent, 0); 16 } 17 return true; 18 } 19 20 @Override 21 public void onActivityResult(int requestCode, int resultCode, Intent intent) { 22 // 根據resultCode判斷處理結果 23 if(resultCode==Activity.RESULT_OK){ 24 String spot=intent.getStringExtra("spot"); 25 context.success(spot); 26 } 27 } 28 }
Activity 被觸發後先通過 setContentView 方法綁定視圖,再從intent 對象中獲取輸入參數進行處理。
完成操作後,通過 Activity 類 setResult(int resultCode, Intent data) 方法綁定返回值,其中resultCode可被 cordovaPlugin 插件用作判斷返回值的處理結果。
最後調用 Activity 對象的 finish 方法關閉 SpotActivity,把返回值回傳到 CordovaPlugin。
1 public class SpotActivity extends Activity{ 2 private CheckBox chk1,chk2,chk3; 3 4 @Override 5 public void onCreate(Bundle savedInstanceState){ 6 super.onCreate(savedInstanceState); 7 //綁定視圖 8 setContentView(R.layout.goods_list); 9 //從intent中獲取輸入參數 10 Integer province=Integer.parseInt(this.getIntent().getStringExtra("province")); 11 setSpots(province); 12 } 13 14 private void setSpots(Integer n){ 15 this.chk1=(CheckBox)this.findViewById(R.id.checkBox1); 16 this.chk2=(CheckBox)this.findViewById(R.id.checkBox2); 17 this.chk3=(CheckBox)this.findViewById(R.id.checkBox3); 18 switch(n){ 19 case 1: 20 chk1.setText("漠河"); 21 chk2.setText("北極村"); 22 chk3.setText("九曲十八灣"); 23 break; 24 case 2: 25 chk1.setText("長白山"); 26 chk2.setText("霧凇島"); 27 chk3.setText("北韓自治州"); 28 break; 29 case 3: 30 chk1.setText("鴨綠江"); 31 chk2.setText("筆架山"); 32 chk3.setText("鳳凰山"); 33 break; 34 default: 35 break; 36 } 37 } 38 39 public void btn_onClick(View view){ 40 String spot=""; 41 if(chk1.isChecked()) 42 spot+=chk1.getText(); 43 if(chk2.isChecked()) 44 spot+=" "+chk2.getText(); 45 if(chk3.isChecked()) 46 spot+=" "+chk3.getText(); 47 //通過setResult綁定返回值 48 Intent intent=new Intent(); 49 intent.putExtra("spot",spot); 50 setResult(RESULT_OK,intent); 51 //關閉該activity,把返回值傳回到cordovaPlugin插件 52 this.finish(); 53 } 54 }
Activity 視圖
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:layout_alignParentBottom="true" 6 android:orientation="vertical" > 7 <TextView 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:text="選擇景點" 11 android:layout_marginTop="80dp"/> 12 <CheckBox 13 android:id="@+id/checkBox1" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content"/> 16 <CheckBox 17 android:id="@+id/checkBox2" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content"/> 20 <CheckBox 21 android:id="@+id/checkBox3" 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content"/> 24 <Button 25 android:id="@+id/button1" 26 style="?android:attr/buttonStyleSmall" 27 android:layout_width="wrap_content" 28 android:layout_height="40dp" 29 android:text="確認" 30 android:layout_marginTop="20dp" 31 android:onClick="btn_onClick"/> 32 </LinearLayout>
activity 關閉後,cordovaPlugin 插件將調用回調函數 onActivityResult(int requestCode, int resultCode, Intent intent),回調函數中可根據 resultCode 參數判斷處理情況,根據不同的結果對intent 中的返回值 bundler 對象進行不同處理。 最後使用 callbackContext 對象中的 success(string) 方法把處理結果回傳到頁面;
處理結果:
本章小結 Cordova(PhoneGap) 技術使用了CordovaPlugin 插件化(模塊化)技術,使用不同插件對不同HTML5頁面進行分別處理。與此同時,系統也可以利用插件調用系統已有的地圖、通信錄、瀏覽器等多個API,與 HTML5 頁面進行信息交換,真正實現HTML5與Android、iOS系統的無縫對接。 參考文章 Cordova(PhoneGap)通過CordovaPlugin插件調用 Activity 實例 最新版Cordova 5.1.1(PhoneGap)搭建開發環境 Apache2.2+Tomcat7.0整合配置詳解 Windows Server 2008 R2 負載平衡入門篇作者:風塵浪子
http://www.cnblogs.com/leslies2/p/cordovaPlugin.html
原創作品,轉載時請註明作者及出處