標籤:phonegap cordova hybrid app android
PhoneGap/Cordova是一個專業的行動裝置 App開發架構,是一個全面的WEB APP開發的架構,提供了以WEB形式來訪問終端裝置的API的功能。這對於採用WEB APP進行開發人員來說是個福音,這可以避免了原生開發的某些功能。Cordova 只是個原生外殼,app的核心是一個完整的webapp,需要調用的原生功能將以原生外掛程式的形式實現,以暴露js介面的方式調用。
Cordova Android項目是Cordova Android原生部分的Java代碼實現,提供了Android原生代碼和上層Web頁面的javascript通訊介面。本系列文章主要分析Cordova Android架構代碼的實現。通過深入分析cordova Android源碼的實現,我們在開發HybridApp時可以更從容,知道Cordova的外掛程式的工作原理,開發cordova外掛程式整合自己的功能模組,在實現web應用時避開js和webview的一些坑,開發出高品質的混合應用。
項目源碼可以在https://git-wip-us.apache.org/repos/asf找到,上面展示了cordova全部子項目的git地址。當你建立cordova應用,並通過cordova platform add Android命令添加android平台後,在應用的platforms/android/CordovaLib/src/org/apache/cordova目錄下面可以找到Cordova Android架構代碼。
cordova3.5版本Android核心架構一共有27個java檔案,代碼量不算大。從cordova3.0版本以後,所有的裝置能力API都從cordova核心架構分離出去,變成了外掛程式,各平台分別進行原生實現,例如訪問裝置資訊的Device外掛程式,訪問網路狀態的Network Information外掛程式,目前官方網站一共收錄了250個外掛程式。下面是 Cordova Android的整體UML類圖,從這張圖上我們看出核心架構和外掛程式之間的關係,外掛程式需要實現CordovaPlugin介面。
Cordova架構類圖
CordovaInterface是Cordova應用的底層介面,CordovaActivity需要實現這個介面。用來隔離Cordova外掛程式開發,隔離外掛程式對Cordova核心庫的直接依賴。
主要方法有startActivityForResult,setActivityResultCallback,getActivity,onMessage,getThreadPool這幾個介面方法。具體的實現在CordovaActivity中。
/** * The Activity interface that is implemented by CordovaActivity. * It is used to isolate plugin development, and remove dependency on entire Cordova library. */public interface CordovaInterface { /** * Launch an activity for which you would like a result when it finished. When this activity exits, * your onActivityResult() method will be called. * * @param command The command object * @param intent The intent to start * @param requestCode The request code that is passed to callback to identify the activity */ abstract public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode); /** * Set the plugin to be called when a sub-activity exits. * * @param plugin The plugin on which onActivityResult is to be called */ abstract public void setActivityResultCallback(CordovaPlugin plugin); /** * Get the Android activity. * * @return the Activity */ public abstract Activity getActivity(); /** * Called when a message is sent to plugin. * * @param id The message id * @param data The message data * @return Object or null */ public Object onMessage(String id, Object data); /** * Returns a shared thread pool that can be used for background tasks. */ public ExecutorService getThreadPool();}
CordovaActivity是Cordova應用的入口類,使用者用來載入html頁面的Activity需要繼承這個Activity。CordovaActivity會讀取Cordova設定檔res/xml/config.xml中的配置。
CordovaActivity繼承了Android Activity,實現了CordovaInterface介面。
比較重要的成員變數有CordovaWebView appView,CordovaWebViewClient webViewClient,用Executors.newCachedThreadPool()初始化了一個線程池threadPool,建立了Activity返回時的回掉外掛程式activityResultCallback,還有就是啟動畫面splashscreen的一些變數等。CordovaActivity繼承了Activity,因此的它的生命週期和Activity一樣,我們可以按照Activity生命週期的順序開始看代碼。
首先看OnCreate方法,首先調用了Config.init(this)方法,讀取config.xml檔案初始化配置,看Config.java的源碼可以知道,該方法主要初始化了url白名單,背景顏色,是否全屏,載入頁面逾時時間(預設20s),啟動畫面延時(預設3s)等。然後是讀取Intent Extra中等一些參數,設定是否顯示標題,是否全屏等。接下來是讀取螢幕寬度和高度,建立一個LinearLayoutSoftKeyboardDetect。LinearLayoutSoftKeyboardDetect這個類是用來檢測軟鍵盤是否彈出的,主要是重寫了onMeasure方法,當軟鍵盤彈出,高度發生變化時發送 app.appView.sendJavascript(“cordova.fireDocumentEvent(‘hidekeyboard’);")事件。我們自己的cordova應用在重新onCreate方法時會依次調用下面的方法。
super.onCreate(savedInstanceState); super.init(); // Set by <content src="index.html" /> in config.xml super.loadUrl(Config.getStartUrl());
CordovaActivity類UML圖
onResume方法首先重新調用了Config.init(this)方法,然後判斷是否是第一次啟動,如果是則直接返回,否則會調用appView.handleResume方法,該方法會觸發javascript事件cordova.fireDocumentEvent(‘resume’),並通知pluginManager,最後進行計數。
onPause方法比較簡單,當appView不為空白時調用appView.handlePause方法,然後去掉啟動畫面SplashScreen。
onDestroy,onNewIntent,postMessage,sendJavascript,showWebPage方法的實現也和onPause方法類似,都是調用了appView的相關方法。
方法addService(String serviceType, String className) 用來添加Service,這個方法已經降級了,以後應該在res/xml/plugins.xml檔案添加。
startActivityForResult方法首先給回調對象activityResultCallback賦值,設定activityResultKeepRunning,最後調用Activity的startActivityForResult方法。
onActivityResult方法當啟動的Activity返回結果時會被調用。首先調用了Activity的onActivityResult方法獲得資料,接著調用mUploadMessage.onReceiveValue(result),最後通過調用activityResultCallback的onActivityResult方法,通知Cordova外掛程式。
onReceivedError方法負責當發生不可恢複的錯誤時,顯示預定義的出錯頁面或錯誤資訊。不可恢複的錯誤是指例如主要資源檔不可用等。如果配置了錯誤頁面,會在UI線程停止進度條,調用appView.showWebPage方法顯示錯誤頁面,否則調用displayError方法彈出錯誤描述對話方塊。
onCreateOptionsMenu,onPrepareOptionsMenu,onOptionsItemSelected這幾個方法類似,都是先調用postMessage發送對應的事件,然後調用父類Activity的對應方法。
onKeyUp和onKeyDown方法都是先調用appView的相關方法,然後調用Activity的相關方法。
本系列第一篇文章先這樣吧,明天下篇文章分析CordovaResourceApi,CordovaWebView,CordovaWebViewClient等幾個類。