1. 程式人生 > 程式設計 >Cordova外掛實現JavaScript與Java的通訊的詳細過程

Cordova外掛實現JavaScript與Java的通訊的詳細過程

背景

Cordova平臺是開源的跨平臺開發框架,被廣泛應用於移動應用開發領域,可以開發跨安卓、iOS等系統的應用。Cordova平臺是基於HTML/javascript語言,它是如何在不同平臺上能夠執行並實現相應功能的呢?這裡就用到了Cordova提供的豐富的外掛,Cordova的大量外掛結合自身的框架,為應用開發者提供了跨平臺的能力,開發者不需要與作業系統層面的介面進行互動,可以關注於應用功能本身。HMS Core為了方便Cordova開發者能夠更方便快速的接入HMS Core的能力,也針對各能力提供了Cordova的外掛

簡介

這裡將結合最常用的華為推送服務Cordova外掛,介紹HMS Core用到的

js-java訊息互動方式,講解在JS側如何呼叫Java側介面,最終實現HMS Core能力。當然,在進行問題定位時也可以參考本文進行分析。

Cordova基本結構

App啟動時,在MainActivity中呼叫loadUrl函式,即觸發了CordovaWebView的初始化,進行Cordova的啟動。此時CordovaWebView會建立PluginManager物件,NativeToJsMessageQueue物件以及JavascriptInterface的ExposedJsApi物件。在後續的訊息互動中,則主要通過ExposedJsApi和NativeToJsMessageQueue進行。

外掛的載入分兩步。首先,在PluginManager物件建立時,讀取配置檔案中的所有Plugin,並建立對映;而在第一次呼叫該外掛時,進行例項化,並執行相關功能。

訊息返回模式包含同步和非同步兩種模式,Cordova中通過在函式中配置async關鍵字進行區分。

對於同步模式,系統會從NativeToJsMessageQueue佇列頭獲取資料,並返回。然後再根據callbackID查詢到請求,返回給success函式。

對於非同步模式,執行後會啟動迴圈函式不停的獲取佇列中的資料。查詢到對應的請求時,返回給success函式。

在華為推送服務的外掛中,採用的是同步的方式。

以推送為樣例說明外掛呼叫方式

如果以上沒有看懂,沒有關係,只要瞭解下面的過程即可。

1. 外掛安裝

執行命令 cordova plugin add @hmscore/cordova-plugin-hms-push 安裝最新外掛。執行後會在plugins中增加外掛資訊。

Cordova外掛實現JavaScript與Java的通訊的詳細過程

其中在plugin.xml中記錄了所有用到的js類,android類等資訊,在plugin初始化時會將其載入到系統中,如果某個函式或介面未在其中進行配置,會導致無法使用。

2. 訊息對映

外掛提供了4種訊息對映方式:

(1) HmsMessaging訊息呼叫

在HmsPush.js中通過runHmsMessaging介面將訊息轉給Android平臺,通過非同步呼叫方式,Android返回的結果將通過Promise返回。

訊息將會轉到HmsPushMessaging類中,在HmsPushMessaging的execute函式中,根據各功能的不同,轉向不同的函式進行處理:

public voidwww.cppcns.com execute(String action,final JSONArray args,final CallbackContext callbackContext)
        throws JSONException {
    hmsLogger.startMethodExecutionTimer(action);
    switch (action) {
        case "isAutoInitEnabled":
            isAutoInitEnabled(callbackContext);
            break;
        case "setAutoInitEnabled":
            setAutoInitEnabled(args.getBoolean(1),callbackContext);
            break;
        case "turnOffPush":
            turnOffPush(callbackContext);
            break;
        case "turnOnPush":
            turnOnPush(callbackContext);
            break;
        case "subscribe":
            subscribe(args.getString(1),callbackContext);
            break;

在各函式呼叫中,通過設定結果的方式,將結果返回給JS層。內容將被寫入nativeToJsMessageQueue佇列中。

callBack.sendPluginResult(new PluginResult(PluginResult.Status.OK,autoInit));

(2) HmsInstanceId訊息呼叫

在HmsPush.js中通過runHmsInstance介面將訊息轉給Android平臺,通過非同步呼叫方式,平臺將結果通過Promise返回。

訊息將會轉到HmsPushInstanceId類中,在HmsPushInstanceId的execute函式中,根據各功能不同,轉向不同的函式處理。

public void execute(String afnGqoLtkction,final CallbackContext callbackContext) throws JSONException {
    if (!action.程式設計客棧equals("init"))
        hmsLogger.startMethodExecutionTimer(action);
 
    switch (action) {
        case "init":
            Log.i("HMSPush","HMSPush initialized ");
            break;
        case "enableLogger":
            enableLogger(callbackContext);
            break;
        case "disableLogger":
            disableLogger(callbackContext);
            break;
        case "getToken":
            getToken(args.length() > 1 ? args.getString(1) : Core.HCM,callbackContext);
            break;
        case "getAAID":
            getAAID(callbackContext);
            break;
        case "getCreationTime":
            getCreationTime(callbackContext);
            break;

最後同樣使用設定結果的方式,將結果返回給JS層。內容將被寫入nativeToJsMessageQueue佇列中。

callBack.sendPluginResult(new PluginResult(PluginResult.Status.OK,autoInit));

過程與HmsPushMessaging非常相似。主要區別在於HmsPushInstanceId用於對映HmsInstanceId相關的介面,HmsPushMessaging用於對映HmsMessaging相關介面。

(3) localNotification訊息呼叫

在HmsLocalNotification.js中通過run介面將訊息傳遞給Android平臺,通過非同步呼叫方式,平臺將結果通過Promise返回。

訊息將會轉到HmsLocalNotification類中,在HmsLocalNotification的execute函式中,根據各功能不同,轉向不同的函式處理。

public void execute(String action,final CallbackContext callbackContext) throws JSONException {
    switch (action) {
        case "localNotification":
   fnGqoLtk         localNotification(args,callbackContext);
            break;
        case "localNotificationSchedule":
            localNotificationSchedule(args.getJSONObject(1),callbackContext);
            break;
        case "cancelAllNotifications":
            cancelAllNotifications(callbackContext);
            break;
        case "cancelNotifications":
            cancelNotifications(callbackContext);
            break;
        case "cancelScheduledNotifications":
            cancelScheduledNotifications(callbackContext);
            break;
        case "cancelNotificationsWithId":
            cancelNotificationsWithId(args.getJSONArray(1),callbackCo程式設計客棧ntext);
            break;

同樣會通過sendPluginResult介面返回處理結果。但是localNotification的訊息涉及訊息傳送,會在傳送完成後進行訊息返回。

(4) Push事件回撥

在Push訊息中除了函式呼叫外,還有很多的事件監聽,比如收到普通訊息,收到透傳訊息,收到Token等,因此在Push中還有對於各種事件的監聽。

對於回撥流程的介紹從Android側開始。

在Android側,Push回撥訊息的函式定義在HmsPushMessageService.java中。

根據SDK的要求,複寫需要用到的回撥函式:onMessageReceived,onDeletedMessages,onNewToken等。

Cordova外掛實現JavaScript與Java的通訊的詳細過程

當事件被觸發時,會向JS層傳送事件通知:

public static void runJS(final CordovaPlugin plugin,final String jsCode) {
    if (plugin == null)
        return;
    Log.d(TAG,"runJS()");
 
    plugin.cordova.getActivity().runOnUiThread(() -> {
        CordovaWebViewEngine engine = plugin.webView.getEngine();
        if (engine == null) {
            plugin.webView.loadUrl("javascript:" + jsCode);
 
        } else {
            engine.evaluateJavascript(jsCode,(result) -> {
 
            });
        }
    });
}

JS側的監聽定義:

在HmsPushEvent.js中對每個事件都進行了定義及註冊

exports.REMOTE_DATA_MESSAGE_RECEIVED = "REMOTE_DATA_MESSAGE_RECEIVED";
exports.TOKEN_RECEIVED_EVENT = "TOKEN_RECEIVED_EVENT";
exports.ON_TOKEN_ERROR_EVENT = "ON_TOKEN_ERROR_EVENT";
exports.NOTIFICATION_OPENED_EVENT = "NOTIFICATION_OPENED_EVENT";
exports.LOCAL_NOTIFICATION_ACTION_EVENT = "LOCAL_NOTIFICATION_ACTION_EVENT";
exports.ON_PUSH_MESSAGE_SENT = "ON_PUSH_MESSAGE_SENT";
exports.ON_PUSH_MESSAGE_SENT_ERROR = "ON_PUSH_MESSAGE_SENT_ERROR";
exports.ON_PUSH_MESSAGE_SENT_DELIVERED = "ON_PUSH_MESSAGE_SENT_DELIVERED";
function onPushMessageSentDelivered(result) {
  window.registerHMSEvent(exports.ON_PUSH_MESSAGE_SENT_DELIVERED,result);
}
exports.onPushMessageSentDelivered = onPushMessageSentDelivered;

需要注意的是,這裡的定義需要在應用開發時主動呼叫,否則不會生效。可以參考Demo中的eventListeners.js。

如果發現已經在Java側觸發回撥,但是沒有接收到,就需要檢查一下Cordova中是否定義有相關呼叫事件。

這樣,在Android側觸發事件時,JS側就可以收到並處理相關的訊息了。如果需要增加新的事件,也可以參考該流程。

小結

通過以上的方式,Push外掛實現了JS側-Java側的訊息互通。在大部分的服務函式介面呼叫中都採用的類似形式。但是對於某些服務,如廣告、地圖等需要顯示圖片或視訊的場景(如地圖,原生廣告等),會用到其他的方式,使用上也更復雜一些,這些會在其他的文件中做詳細的介紹。

>>訪問HMS Core官網,瞭解更多相關內容
>>獲取HMS Core Cordova外掛開發指導文件
>>華為HMS Core官方論壇
>>華為HMS Core Cordova外掛開源倉庫地址:github

以上就是Cordova外掛如何實現JavaScript與Java的通訊的詳細內容,更多關於Cordova外掛JavaScript與Java通訊的資料請關注我們其它相關文章!