Hybrid programming

Android hybrid programming mainly needs to achieve JSBridge, which is the bridge between H5 and Native communication, and its role is to achieve two-way communication between H5 and Native.

Key points of JSBridge implementation

  • How does Java call JavaScript
  • How does JavaScript call Java
  • How are method parameters and callbacks handled
  • Development of communication protocols

How does Java call JavaScript

Js calls Android in the following four ways:

  1. The WebView JavascriptInterface
  2. WebViewClient.shouldOverrideUrlLoading()
  3. WebChromeClient.onConsoleMessage()
  4. WebChromeClient. OnJsPrompt (), onJsAlert (), onJsConfirm ()

We will first give a detailed description of these four schemes, and finally choose a scheme. The fourth scheme is adopted in this paper.

Why onJsPrompt

WebChromeClient.onJsPrompt()

Have a method in the WebView, called setWebChromeClient, you can set the WebChromeClient object, and there are three methods in the object, respectively is onJsAlert, onJsConfirm, onJsPrompt, Window. alert, window.confirm, window.prompt and WebChromeClient will be triggered when JS calls the corresponding methods of the window object, namely window.alert, window.confirm, window.prompt and WebChromeClient.

  1. See the W3C JavaScript message box for the differences between these three methods.
  2. In general, we don’t use onJsAlert, why? Because the frequency of using alert in JS is still very high, once we occupy this channel, the normal use of alert will be affected, while the frequency of using confirm and prompt is lower than that of alert.
  3. In fact, the frequency of use of confirm is not low. For example, when you click a link to download a file, if you need to pop up a prompt for confirmation, click OK and the file will be downloaded, while click cancel and the file will not be downloaded. There are many similar scenarios. Therefore, confirm cannot be used.
  4. Prompt, on the other hand, is almost never used in Android, and if it is, it is customized, so you can use it. The idea is to pop up an input box, ask you to type it, and then return what’s in the input box. Therefore, the occupation prompt is perfect.

Method parameters and callback processing

  1. Any IPC communication involves the issue of parameter serialization, and in the same way, Java and JavaScript can only pass basic types (including basic types and strings) to each other, not other objects or functions. So you can pass the data in JSON format.
  2. In order to achieve asynchronous return results, so JavaScript and Java call each other can not directly get the return value, only through the way of callback to get the return result.

Development of communication protocols

To carry on the normal communication, the communication protocol formulation is essential. Let’s recall the familiar components of an HTTP request URL. Like http://host:port/path? Param =value, we refer to HTTP to formulate the components of JSBridge.

The specific operational

Calling process

In JS, Java methods can be called as follows:

var JSBridge = {

call: function(className, method, params, callback) {

var uri = ‘jsbridge://’ + className + ‘:’ + callback + ‘/’ + method + ‘? ‘ + params;

​ window.prompt(uri, “”);

}

}

// The bridge. ShowToast method in Java is called

JSBridge.call(‘bridge’, ‘showToast’, {‘msg’:’Hello JSBridge’}, function(res) {

​ alert(JSON.stringify(res))

​ });

In Java, this can be implemented as follows:

// Enter the prompt callback

public class JSBridgeWebChromeClient extends WebChromeClient {

​ @Override

​ public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {

​ result.confirm(JSBridge.callJava(view, message));

​ return true;

​ }

}

// Invoke Java logic

public class JSBridge {

.

​ public static String callJava(WebView webView, String uriString) {

​ String methodName = “”;

​ String className = “”;

​ String param = “{}”;

​ String port = “”;

if (! TextUtils.isEmpty(uriString) && uriString.startsWith(“JSBridge”)) {

​ Uri uri = Uri.parse(uriString);

​ className = uri.getHost();

​ param = uri.getQuery();

​ port = uri.getPort() + “”;

​ String path = uri.getPath();

if (! TextUtils.isEmpty(path)) {

​ methodName = path.replace(“/”, “”);

​ }

​ }

// Call the corresponding class method based on className, methodName, and port path above

​ if (exposedMethods.containsKey(className)) {

​ HashMap<String, Method> methodHashMap = exposedMethods.get(className);

if (methodHashMap ! = null && methodHashMap.size() ! = 0 && methodHashMap.containsKey(methodName)) {

​ Method method = methodHashMap.get(methodName);

if (method ! = null) {

​ try {

​ method.invoke(null, webView, new JSONObject(param), new Callback(webView, port));

​ } catch (Exception e) {

​ e.printStackTrace();

​ }

​ }

​ }

​ }

​ return null;

​ }

}

// Go directly to the implementation of the showToast function

public static void showToast(WebView webView, JSONObject param, final Callback callback) {

​ String message = param.optString(“msg”);

​ Toast.makeText(webView.getContext(), message, Toast.LENGTH_SHORT).show();

if (null ! = callback) {

​ try {

​ JSONObject object = new JSONObject();

​ object.put(“key”, “value”);

​ object.put(“key1”, “value1”);

​ callback.apply(getJSONObject(0, “ok”, object));

​ } catch (Exception e) {

​ e.printStackTrace();

​ }

​ }

}

// The callback.apply method is implemented as follows: that is, webView.loadUrl is implemented as Java calling js method