DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Embed a Spreadsheet Into Your Web App
  • Code Play #1: WebSockets With Vert.x and Angular
  • Understanding Java Signals
  • Enhance User Experience With a Formatted Credit Card Input Field

Trending

  • Java Virtual Threads and Scaling
  • Performance Optimization Techniques for Snowflake on AWS
  • Contextual AI Integration for Agile Product Teams
  • How to Format Articles for DZone
  1. DZone
  2. Coding
  3. Languages
  4. Cordova: Communicating Between JavaScript and Java

Cordova: Communicating Between JavaScript and Java

Frontend, meet the backend.

By 
Jackson Jiang user avatar
Jackson Jiang
DZone Core CORE ·
Nov. 30, 21 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
7.6K Views

Join the DZone community and get the full member experience.

Join For Free

Background

Cordova is an open-source cross-platform development framework that allows you to use HTML and JavaScript to develop apps across multiple platforms, such as Android and iOS. So how exactly does Cordova enable apps to run on different platforms and implement the functions? The abundant plugins in Cordova are the main reason, and free you to focus solely on app functions, without having to interact with the APIs at the OS level. 

Introduction

Here, I'll use the Cordova plugin in HUAWEI Push Kit as an example to demonstrate how to call Java APIs in JavaScript through JavaScript-Java messaging. The following implementation principles can be applied to all other kits, except for Map Kit and Ads Kit (which will be detailed later), and help you master troubleshooting solutions.

Basic Structure of Cordova

When you call style='mso-bidi-font-weight:normal'>loadUrl in MainActivity, CordovaWebView will be initialized and Cordova starts up. In this case, style='mso-bidi-font-weight:normal'>CordovaWebView will create style='mso-bidi-font-weight:normal'>PluginManager, NativeToJsMessageQueue, as well as ExposedJsApi of JavascriptInterface. style='mso-bidi-font-weight:normal'>ExposedJsApi and NativeToJsMessageQueue will play a role in the subsequent communication.

During the plugin loading, all plugins in the configuration file will be read when the PluginManager object is created, and plugin mappings will be created. When the plugin is called for the first time, instantiation is conducted and related functions are executed.

A message can be returned from Java to JavaScript in synchronous or asynchronous mode. In Cordova, set async in the method to distinguish the two modes.

In synchronous mode, Cordova obtains data from the header of the NativeToJsMessageQueue queue, finds the message request based on callbackID, and returns the data to the success method of the request.

In asynchronous mode, Cordova calls the loop method to continuously obtain data from the NativeToJsMessageQueue queue, finds the message request, and returns the data to the success method of the request.

In the Cordova plugin of Push Kit, the synchronization mode is used.

Plugin Call

You may still be unclear on how the process works, based on the description above, so I've provided the following procedure:

1. Install the Plugin

Run the cordova plugin add @hmscore/cordova-plugin-hms-push command to install the latest plugin. After the command is executed, the plugin information is added to the plugins directory. 

The plugin.xml file records all information to be used, such as JavaScript and Android classes. During the plugin initialization, the classes will be loaded to Cordova. If a method or API is not configured in the file, it is unable to be used.

2. Create a Message Mapping

The plugin provides the methods for creating mappings for the following messages:

(1) HmsMessaging

In the HmsPush.js file, call the runHmsMessaging API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.

The message will be transferred to the HmsPushMessaging class. The execute method in HmsPushMessaging can transfer the message to a method for processing based on the action type in the message. 

 
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;

(2) HmsInstanceId
In the HmsPush.js file, call the runHmsInstance API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsPushInstanceId class. The execute method in HmsPushInstanceId can transfer the message to a method for processing based on the action type in the message. 

 
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;

Similarly, the processing method returns the result to JavaScript. The result will be written to the nativeToJsMessageQueue queue. 

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

(3) localNotification
In the HmsLocalNotification.js file, call the run API in asynchronous mode to transfer the message to the Android platform. The Android platform returns the result through Promise.
The message will be transferred to the HmsLocalNotification class. The execute method in HmsLocalNotification can transfer the message to a method for processing based on the action type in the message. 

 
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;

Call sendPluginResult to return the result. However, for localNotification, the result will be returned after the notification is sent.

3. Perform Message Push Event Callback

In addition to the method calling, message push involves listening for many events, for example, receiving common messages, data messages, and tokens.

The callback process starts from Android.

In Android, the callback method is defined in HmsPushMessageService.java.

Based on the SDK requirements, you can opt to redefine certain callback methods, such as onMessageReceived, onDeletedMessages, and onNewToken.

When an event is triggered, an event notification is sent to 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) -> {

});
}
});
}

Each event is defined and registered in 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;

Please note that the event initialization needs to be performed during app development. Otherwise, the event listening will fail. For more details, please refer to eventListeners.js in the demo. If the callback has been triggered in Java, but is not received in JavaScript, check whether the event initialization is performed. In doing so, when an event is triggered in Android, JavaScript will be able to receive and process the message. You can also refer to this process to add an event. 

Summary

The description above illustrates how the plugin implements the JavaScript-Java communications. The methods of most kits can be called in a similar manner. However, some kits require a different method, which will be introduced in a later article. 

Apache Cordova JavaScript Java (programming language) Android (robot) Event

Opinions expressed by DZone contributors are their own.

Related

  • Embed a Spreadsheet Into Your Web App
  • Code Play #1: WebSockets With Vert.x and Angular
  • Understanding Java Signals
  • Enhance User Experience With a Formatted Credit Card Input Field

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!