preface

Now there are more and more hybrid mobile apps, such as Alipay, wechat, JINGdong and other mainstream apps, which are embedded with many H5 apps. These H5 apps are essentially web pages that run on the phone’s WebView rendering. While this is cross-platform, these pages do not have the ability to call native devices directly. Based on this, JS Bridge becomes the key of H5 application and native communication.

1 What is JS Bridge

A JS Bridge is actually a piece of JS code that encapsulates H5’s access to native methods. Native H5 access methods can act as a “Bridge” between H5 and native.

2. JS Bridge technology

To implement the JS Bridge, we need to follow these steps:

  • Step 1: Define a global bridge object that Native interacts with JS
  • Step 2: JS calls Native
  • Step 3: Native receives the parameters passed by the JS
  • Step 4: Native returns data to JS
  • Step 5: THE JS accepts the parameters passed in native
  • Step 6: Callback event handling

2.1 Global bridge objects

Define a global bridge object. Later, we need to use it to access the methods we defined to “communicate” with the native.

var JSBridge = window.JSBridge || (window.JSBridge = {})
Copy the code

2.2 JS call native

Android officially encapsulates the interface as to how JS actively calls native. You first need to create JS access native namespace: webView. AddJavascriptInterface (this, “androidPlatform”); There was an official explanation for this method,

Injects the supplied Java object into this WebView. The object is injected into all frames of the web page, including all the iframes, using the supplied name. Inject the supplied Java object into this WebView. Inject the provided namespace into all frames of the page, including all iframes. This allows methods to access Java objects from JavaScript.

After the Android namespace is defined, JS can pass data to the native via this namespace:

window.androidPlatform.postString(jsonStr); // This passes the argument to the native postString method
Copy the code

2.3 Native receives the parameters passed by JS

Create a postString method in the Java object passed to the webView to receive the data passed by JS.

@JavascriptInterface // Since Android 4.2, postString methods must be annotated in order to be accessed by JS
public void postString(String jsonStr) {
    // jsonStr is the data passed by JS
}
Copy the code

2.4 Native returns data to JS

Android webView provides a method for how Native returns data to JS.

final String script = "javascript:window.JSBridge.postMsg(" + data + ")";
webView.evaluateJavascript(script, null));
Copy the code

2.5JS accepts arguments passed natively

// JS defines the window,JSBridge. PostMsg method to receive data
JSBridge.postMsg = function postMsg(result) {
    // Process the returned data
}
Copy the code

2.6 Handling callback Events

In general, JS calls native methods and expects to get data back. So JSBridge might be better off returning an asynchronous Promise to the caller, waiting until the data is returned native and then receiving the data through that Promise.

// Call native via jsbridge.call
window.JSBridge.call(data).then();

// jsbridge.call () returns Promise
JSBridge.call = function (data) {
  / / return Promise
  return new Promise(function (resolve, reject) {
    JSBridge.callNative(data, {
      resolve: resolve,
      reject: reject
    });
  });
};

// Perform the actual access here
// callbacks={} Cache all callback events
JSBridge.callNative = function callNative(data, responseCallback) {
  try {
    var callbackId = '0';
    if (callbacks && typeof responseCallback.resolve === 'function') {
      callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime(); // Generate a unique callbackId
      callbacks[callbackId] = responseCallback; // Save the callback event
    }
    / / native
    // Perform operations described in 2.2 to access native
  } catch (e) {
    console.error(e);
  }
  return null;
}

// Data is returned to JSBridge natively, as shown in 2.4 and 2.5
// If the front-end wants to get asynchronous results in then(), it needs to be in 2.5 (jsbridge.postmsg)
// retrieve the callback event execution via callbackId
JSBridge.postMsg = function postMsg(result) {
  // Process the returned data
  var call = callbacks[result.callbackId]; // The callbackId needs to "follow" the call throughout
  // call.resolve(result.data); // Resolve resolve successfully
  // call.reject(result.error); // Fail reject
  // If you don't understand this, you can go to JS Promise.
}
Copy the code

The 3 is at the end

JS Bridge is not difficult to implement, the essence is to call the Android/iOS native platform provided JS call interface, do some interface encapsulation. If the code above seems a bit messy, go to GitHub and take a look at the full code in the demo. JSBridgeDemo