Предыстория
Cordova — это кроссплатформенная среда разработки с открытым исходным кодом, которая позволяет использовать HTML и JavaScript для разработки приложений на нескольких платформах, таких как Android и iOS. Как Cordova позволяет приложениям работать на разных платформах и реализовывать функции? Все дело в многочисленных плагинах в Cordova. Они позволяют сосредоточиться исключительно на функциях приложения, не взаимодействуя с API на уровне ОС.
Введение
Я буду использовать плагин Cordova в HUAWEI Push Kit в качестве примера, чтобы показать, как вызывать API Java в JavaScript через обмен сообщениями JavaScript-Java. Следующие принципы реализации помогут вам освоить решения по устранению неполадок. Их можно применить и к другим наборам средств разработки.
Базовая структура Cordova
При вызове параметра loadUrl в MainActivity будет инициализирован параметр CordovaWebView, после чего запустится Cordova. Затем CordovaWebView создаст параметры PluginManager, NativeToJsMessageQueue, а также ExposedJsApi для JavascriptInterface. Параметры ExposedJsApi и NativeToJsMessageQueue будут использоваться в последующем обмене данными.
Во время загрузки плагина создается объект PluginManager, считываются все плагины в файле конфигурации, а затем выполняется мапирование плагинов. При первом вызове плагина создается экземпляр класса и выполняются связанные функции.
Сообщение может быть возвращено из Java в JavaScript в синхронном или асинхронном режиме. В Cordova установите параметр async в методе, чтобы различать два режима.В синхронном режиме Cordova получает данные из заголовка очереди NativeToJsMessageQueue, находит запрос сообщения на основе callbackID и возвращает данные в метод success запроса.
В асинхронном режиме Cordova вызывает метод цикла для непрерывного получения данных из очереди NativeToJsMessageQueue, находит запрос сообщения и возвращает данные в метод success запроса.
В плагине Cordova для Push Kit используется режим синхронизации.
Вызов плагина
Теперь рассмотрим процесс вызова плагина подробнее.
1.Установите плагин.
Запустите команду cordova plugin add @hmscore/cordova-plugin-hms-push, чтобы установить последнюю версию плагина. После выполнения команды данные плагина будут добавлены в каталог plugins.
Файл plugin.xml записывает всю используемую информацию, такую как классы JavaScript и Android. Во время инициализации плагина классы будут загружены в Cordova. Метод или API нельзя использовать, если они не настроены в файле.
2.Выполните мапирование сообщений.
Плагин предоставляет методы для выполнения мапирования следующих сообщений.
(1) HmsMessaging
В файле HmsPush.js вызовите API runHmsMessaging в асинхронном режиме, чтобы передать сообщение на платформу Android. Платформа Android возвратит результат через параметр Promise.
Сообщение будет передано в класс HmsPushMessaging. Метод execute в HmsPushMessaging может передать сообщение методу для обработки в зависимости от типа действия в сообщении.
public void 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;
Метод обработки возвращает результат в JavaScript. Результат будет записан в очередь nativeToJsMessageQueue.
callBack.sendPluginResult(new PluginResult(PluginResult.Status.OK,autoInit));
(2) HmsInstanceId
В файле HmsPush.js вызовите API runHmsInstance в асинхронном режиме, чтобы передать сообщение на платформу Android. Платформа Android возвратит результат через параметр Promise.
Сообщение будет передано в класс HmsPushInstanceId. Метод execute в HmsPushInstanceId может передать сообщение методу для обработки в зависимости от типа действия в сообщении.
public void execute(String action, final JSONArray args, 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;
Точно так же метод обработки возвращает результат в JavaScript. Результат будет записан в очередь nativeToJsMessageQueue.
callBack.sendPluginResult(new
PluginResult(PluginResult.Status.OK,autoInit));
Этот процесс аналогичен процессу для класса HmsPushMessaging. Основное отличие состоит в том, что HmsInstanceId используется для API, связанных с HmsPushInstanceId, а HmsMessaging — для API, связанных с HmsPushMessaging.
(3) localNotification
В файле HmsLocalNotification.js вызовите API run в асинхронном режиме, чтобы передать сообщение на платформу Android. Платформа Android возвратит результат через параметр Promise.
Сообщение будет передано в класс HmsLocalNotification. Метод execute в HmsLocalNotification может передать сообщение методу для обработки в зависимости от типа действия в сообщении.
public void execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
switch (action) {
case "localNotification":
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), callbackContext);
break;
Вызовите sendPluginResult, чтобы вернуть результат. Однако для параметра localNotification результат будет возвращен после отправки уведомления.
Выполните обратный вызов события push-сообщения
Помимо вызова метода, отправка сообщений включает прослушивание многих событий, например получение обычных сообщений, сообщений с данными и токенов.
Процесс обратного вызова начинается с Android. В Android метод обратного вызова определяется в параметре HmsPushMessageService.java. В зависимости от требований SDK вы можете переопределить некоторые методы обратного вызова, такие как onMessageReceived, onDeletedMessages и onNewToken.
При запуске события уведомление о нем отправляется в JavaScript.
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) -> {
});
}
});
}
Каждое событие определяется и регистрируется в файле 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;
Хочу обратить ваше внимание, что инициализацию события нужно выполнить во время разработки приложения. В противном случае произойдет сбой при прослушивании событий. Дополнительные сведения см. в файле eventListeners.js демонстрации.
Если обратный вызов был активирован в Java, но не получен в JavaScript, проверьте, выполнена ли инициализация события.
Таким образом, когда событие запустится в Android, JavaScript сможет получить и обработать сообщение. Аналогичным образом вы можете добавить событие.
Итог
Сегодня мы рассмотрели, как плагин реализует связь между JavaScript и Java. Подобным образом можно вызвать методы большинства наборов средств разработки.
DrRaznomazov
Спасибо за статью. Ранее с подобной концепцией сталкивалась в рамках известного фреймворка vaadin. И уже тогда сложилось впечатление, что она (концепция) хорошая для решений малого бизнеса, когда тмеет смысл экономить на веб-разработчиках. А вот для крупных проектов, таких как банки, хорошо бы разнести фронт и бек разратотки по разным точкам. Хотелось бы узнать мнение авторов, на сколько данная концепция применима в энтерпрайсе? На сколько хорошо она ложится под ci/cd ?