Cordova外掛實現JavaScript與Java的通訊的詳細過程
背景
Cordova平臺是開源的跨平臺開發框架,被廣泛應用於移動應用開發領域,可以開發跨安卓、iOS等系統的應用。Cordova平臺是基於HTML/javascript語言,它是如何在不同平臺上能夠執行並實現相應功能的呢?這裡就用到了Cordova提供的豐富的外掛,Cordova的大量外掛結合自身的框架,為應用開發者提供了跨平臺的能力,開發者不需要與作業系統層面的介面進行互動,可以關注於應用功能本身。HMS Core為了方便Cordova開發者能夠更方便快速的接入HMS Core的能力,也針對各能力提供了Cordova的外掛。
簡介
這裡將結合最常用的華為推送服務Cordova外掛,介紹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中增加外掛資訊。
其中在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等。
當事件被觸發時,會向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通訊的資料請關注我們其它相關文章!