Cordova外掛中JavaScript程式碼與Java的互動細節介紹

i042416發表於2018-08-23

在Cordova官網中有這麼一張架構圖:大家看右下角藍色的矩形框"Custom Plugin"——自定義外掛。意思就是如果您用Cordova打包Mobile應用時,發現您的移動應用裡需要使用一些功能,這些功能用普通的JavaScript無法實現,而是需要呼叫移動平臺的一些原生API才能實現時,我們就需要自己實現自定義外掛。這些外掛透過在特定的移動平臺上採用原生開發實現,比如Android Studio中的Java開發,然後再透過JavaScript wrapper的方式暴露給您的Mobile應用。比如您是用Cordova在Android平臺上打包生成APK檔案,那麼您的Mobile程式碼(JavaScript)裡還是不會直接呼叫您用Java實現的Custom Plugin,而是呼叫Custom Plugin對應的JavaScript wrapper。

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

那麼JavaScript wrapper本身是JavaScript程式碼,它是怎麼呼叫到Custom Plugin的Java實現的?本文就會介紹這個細節。

下圖是OData離線儲存外掛(OData Offline Store)的JavaScript實現程式碼的一部分。下圖第232行會呼叫裝置的native API進行離線儲存的開啟操作:

exec(win, error, 'OData', 'openOfflineStore', [this, options ? options : {}]);

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

這個exec函式從哪裡來?由Cordova框架實現,透過語句 require(‘cordova/exec’)返回。

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

那麼當應用執行到JavaScript程式碼:exec(win, error, 'OData', 'openOfflineStore', [this, options ? options : {}]); 的時候,程式流是如何從這個JavaScript的exec函式進入到Android平臺的原生API執行呢?

開啟PackagedApp資料夾裡的android子資料夾,有一個JavaScript檔案:cordova.js:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

裡面能看到函式exec的定義和實現:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

進而去檢視androidExec函式的實現細節:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

第938行:var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);

第943行的五個引數含義:

success, fail, service, action, args

  • success & fail: JavaScript回撥函式,當移動平臺上的Java原生API執行完畢後,這個JavaScript回撥函式會被呼叫到。

  • service: 待執行的Java Native API的Java實現類名稱。

  • action: 待執行的Java Native API的Java實現類的方法名稱。

  • args: JavaScript傳遞給Java native API的引數陣列。

2. 在安卓平臺上,JavaScript呼叫Java的技術實現方式有兩種:定義在下圖JavaScript程式碼中的jsToNativeModes物件中:PROMPT和JS_OBJECT。相對應的,Java呼叫JavaScript有三種模式:POLLING, LOAD_URL和ONLINE_EVENT:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

看下面這段Java程式碼,暴露了一個方法getSomeString給JavaScript端消費:

import android.app.Activity;import android.os.Bundle;import android.webkit.WebView;public class WebViewGUI extends Activity {
    WebView mWebView;    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        mWebView = new WebView(this);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.addJavascriptInterface(new JavaScriptInterface(),                "jsinterface");
        mWebView.loadUrl("file:///android_asset/www/index.html");
        setContentView(mWebView);
    }    final class JavaScriptInterface {
        JavaScriptInterface() {
        }        public String getSomeString() {            return "string";
        }
    }
}

在JavaScript程式碼裡消費上述Java程式碼暴露的getSomeString方法:

<script>var String = window.jsinterface.getSomeString();</script>

我們再回過頭來看看AndroidExec的實現:

var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);

在AndroidExec的實現裡, nativeApiProvider的get方法返回一個例項,然後執行exec方法。而881行程式碼說明nativeApiProvider的實現位於資料夾cordova/android下面的nativeapiprovider.js裡:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

開啟nativeapiprovider.js,在第21行的註釋裡我們得到了重要資訊: currentApi要麼來自Java檔案ExposedJsApi.java,要麼來自PromptBasedNativeApi.java。

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

Java檔案ExposedJsApi.java可以在這個資料夾內找到:

platform/android/CordovaLib/src/org/apache/cordova

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

ExposedJsApi實際就是個Java interface,上面宣告瞭一個exec方法:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

JavaScript到Java的執行透過prompt呼叫完成:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

Java類SystemExposedJsApi實現了這個interface,再將執行流轉交給類CordovaBridge的例項.

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

CordovaBridge再呼叫PluginManager:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

PluginManager首先根據名字找到負責處理該請求的Java plugin的實現類,再呼叫該實現類的方法:

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

以OData離線儲存的實現類為例,我們在其實現程式碼裡能發現有大量的IF-ELSE分支,每個分支處理不同的離線儲存操作請求。

Cordova外掛中JavaScript程式碼與Java的互動細節介紹

要獲取更多Jerry的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:


Cordova外掛中JavaScript程式碼與Java的互動細節介紹

Cordova外掛中JavaScript程式碼與Java的互動細節介紹


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2212655/,如需轉載,請註明出處,否則將追究法律責任。

相關文章