html5 + primordial js intermodulation

With the rapid development of the mobile Internet, the conventional development speed has gradually been unable to meet the market demand. Native H5 hybrid development came into being. At present, many mainstream applications in the market use hybrid development, such as Alipay and Meituan. Next, based on my own development experience, I will briefly talk about the understanding and implementation of hybrid development.

The advantages of hybrid development The

advantages are obvious. Front-end engineers can write a page and run on multiple platforms, saving Android and iOS engineers a lot of work, improving development efficiency and saving development costs.

Disadvantages

Anyone who has used it knows that the interface of the H5 is displayed on the mobile phone, and the response to events such as clicks, touches, and slides is not as smooth as the native controls, and even lags may occur. This is also normal. If the experience is as good as the native controls, there will be no android (ios) engineer. There may be many ways

for H5 to call native . According to my own development experience, I have come across two ways. The first 1. First initialize WebView WebSettings settings = webview.getSettings(); settings.setJavaScriptEnabled(true); //Allow js to be used in WebView 2. Create a class JavaScriptMetod, which is specially used to provide callable to js Method 3. Create a constructor for this class and provide two parameters, the WebView object and the context object private Context mContext; private WebView mWebView;















public JavaScriptMethod(Context context, WebView webView) {
mContext = context;
mWebView = webView;
}
4. Create a string constant as the interface for communication between android and js, that is, the string mapping object

public static final String JAVAINTERFACE = "javaInterface";
5. The next step is to create a method to be called by js. The parameter of the method receives a json string (note: after Android 4.2, in order to improve code security, the method must be annotated with @JavascriptInterface, otherwise it cannot be called)

@JavascriptInterface
// Andorid4.2 (including android4.2) and above, if this annotation is not written, js cannot call the android method
public void showToast(String json){
Toast.makeText(context, json, Toast.LENGTH_SHORT).show();
}
6. Execute the following code in the WebView initialization code,

//Create the object of the class created above
JavaScriptMetod m = new JavaScriptMetod(this, webview);
//In fact, it is to tell js which object I provide to you to call, so that js can call the object method inside
//The second parameter is the string constant in this class
webview.addJavascriptInterface(m, JavaScriptMetod.javaInterface);
now, the method in JavaScriptMetod can be called in js, the calling method is as follows

//The parameter is generally in json format
var json = {"name":"javascript"};
//javaInterface is the string mapping object mentioned above
window.javaInterface.showToast(JSON.stringify(json));
In the article on the Internet that introduces the native interaction between js and android, Most of them are the above methods, but this method does not apply to ios, that is to say, the js code such as window.javaInterface.showToast(JSON.stringify(json)) does not apply to ios. If the above method is used method, you have to write a set of js code for android and ios respectively. This is obviously unreasonable, so in actual development, the next second method is generally used.

The second idea implemented by

this method is that js makes a url request and adds the required parameters to that url. The android side intercepts the url through webView.setWebViewClient(), parses the parameters carried in the url, and performs corresponding operations according to the parameter information.

1. Same as method 1, you need to initialize the webview first.

WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true); //Allow js to be used in WebView
2. First look at how the code in js is written,

$("#showtoast").click(function () {
var json = {"data": "I am a toast"};
window.location.href="protocol://android?code=toast&data="+JSON.stringify(json);
});
$("#call").click(function () {
var json = {"data": "10086"};
window.location.href="protocol://android?code=call&data="+JSON.stringify(json);
});
here define two click events, Control the android display toast and call operations respectively. Among them, protocol://android is a customized communication protocol between H5 and android, which is distinguished from http requests. code specifies the operation to be performed, and data is the transmitted data.

2. The code

webView in android.


/**
* By judging whether the intercepted url contains pre, to distinguish whether it is an http request or a request to call an android method
*/
String pre = "protocol://android";
if (!url.contains(pre)) {
/ /The url is an http request, use webview to load the url
return false;
}
//The url is a request to call the android method, and execute the corresponding method by parsing the parameters in the url
Map<String, String> map = getParamsMap(url, pre) ;
String code = map.get("code");
String data = map.get("data");
parseCode(code, data);
return true;
}
});
where the getParamsMap() method intercepts the url from Parse out the code and data parameters, and the parseCode() method will perform corresponding operations according to different codes. The code is as follows:

private Map<String, String> getParamsMap(String url, String pre) {
ArrayMap<String, String> queryStringMap = new ArrayMap < >();
if (url.contains(pre)) {
int index = url.indexOf(pre);
int end = index + pre.length();
String queryString = url.substring(end + 1);

String[] queryStringSplit = queryString.split("&");

String[] queryStringParam;
for (String qs : queryStringSplit) {
if (qs.toLowerCase().startsWith("data=")) {
//单独处理data项,避免data内部的&被拆分
int dataIndex = queryString.indexOf("data=");
String dataValue = queryString.substring(dataIndex + 5);
queryStringMap.put("data", dataValue);
} else {
queryStringParam = qs.split("=");

String value = "";
if (queryStringParam.length >1) {
//Avoid passing values ​​in the background sometimes, such as "key="
value = queryStringParam[1];
}
queryStringMap.put(queryStringParam[0].toLowerCase(), value);
}
}
}
return queryStringMap;
}

private void parseCode(String code, String data) {
if(code.equals("call")) {
try {
JSONObject json = new JSONObject(data);
String phone = json.optString("data");
//执行打电话的操作,具体代码省略
PhoneUtils.call(this, phone);
} catch (JSONException e) {
e.printStackTrace();
}
return;
}
if(code.equals("toast")) {
try {
JSONObject json = new JSONObject(data);
String toast = json.optString("data");
Toast.makeText(this, toast, Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
return;
}
}
Finally, special Explain the return value of the shouldOverrideUrlLoading() method. There are three types of return values:

1. Return true, that is, perform the corresponding operation according to the code logic, and the webview does not load the url;

2. Return false, in addition to executing the corresponding code, the webview Load the url;

3. Return to super.shouldOverrideUrlLoading(), click into the parent class, we can see that the returned value is still false.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325941529&siteId=291194637