Cordova Android源代碼分析系列一(項目總覽和CordovaActivity分析)

版權聲明:本文爲博主offbye西濤原創文章。未經博主贊成不得轉載。 https://blog.csdn.net/offbye/article/details/31776833

PhoneGap/Cordova是一個專業的移動應用開發框架,是一個全面的WEB APP開發的框架,提供了以WEB形式來訪問終端設備的API的功能。

這對於採用WEB APP進行開發人員來講是個福音。這可以避免了原生開發的某些功能。javascript

Cordova 僅僅是個原生外殼,app的內核是一個完整的webapp。需要調用的原生功能將以原生插件的形式實現,以暴露js接口的方式調用。html


       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框架代碼。 java

       cordova3.5版本號Android核心框架一共同擁有27個java文件,代碼量不算大。從cordova3.0版本號之後。全部的設備能力API都從cordova核心框架分離出去,變成了插件,各平臺分別進行原生實現,好比訪問設備信息的Device插件,訪問網絡狀態的Network Information插件。眼下官方站點一共收錄了250個插件。如下是 Cordova Android的整體UML類圖,從這張圖上咱們看出核心框架和插件之間的關係。插件需要實現CordovaPlugin接口。android


Cordova框架類圖git

   


  • CordovaInterface接口分析

           CordovaInterface是Cordova應用的底層接口,CordovaActivity需要實現這個接口。web

用來隔離Cordova插件開發,隔離插件對Cordova核心庫的直接依賴。apache

   主要方法有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核心類分析


       CordovaActivity是Cordova應用的入口類,用戶用來載入html頁面的Activity需要繼承這個Activity。app

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等幾個類。