Currently, APP is divided into the following technologies
- Webapp, cordova, Ionic, etc
- Hybrid, Native+ H5 mode
- React Native, weex direction
- Pure Native, there’s nothing to say about that
- This article only describes the implementation principle of Hybrid jsbrige, and will not touch on the design of Native webView. There are too many articles on webview, please refer to other articles
Communication principle
Pre-defined schema, such as myapp://… Sends a pseudo-connection request iframe.src through the front end
var iframe = document.createElement('iframe')
iframe.style.display = 'none'
iframe.src = schema
var body = document.body
body.appendChild(iframe)
setTimeout(function () {
body.removeChild(iframe)
iframe = null
})
Copy the code
As you can see, when a button or action needs to communicate with a Native, create an iframe and then remove it. If you do not remove the iframe, there will be a large number of useless IFrame tags in the body. Here is a brief description of how Native intercepts this pseudo-link request. Override a method in the WebviewClient:
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(SCHEMA)) {
...
return true; }}Copy the code
Parameter passing
In actual projects, parameters must be passed to Native to receive, which can be encapsulated in this way
for (key in data) {
if (data.hasOwnProperty(key)) {
schema += '&' + key + data[key]
}
}
Copy the code
In this way, the form &key=value can be spliced. The Native terminal can write a method to obtain the values of key and value and then do corresponding processing.
Methods the callback
Sometimes after the bridge event is processed, some feedback needs to be told to the front-end, so the front-end needs to encapsulate a callbackName to the Native end
var callbackName = ' '
if (typeof callback === 'string') {
callbackName = callback
} else {
callbackName = action + Date.now()
console.log('callbackName: ' + callbackName)
window[callbackName] = callback
}
schema += 'callback=' + callbackName
Copy the code
Special note: there is a date.now (), which is used to avoid repeated callbacks and to avoid blocking the UI from responding to repeated clicks on aN ios phone.
Native execution callback written:
public static void call(WebView webview, String js) {
if(webview ! = null) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webview.evaluateJavascript(js, null);
} else {
webview.loadUrl("javacript:"+ js); }}}Copy the code
Usage, for example,
After jSbrige is packaged, it can be tested. Take sharing as an example:
window.bridge.share({
title: '... ',
content: '... '
}, function (result) {
if (result.success) {
alert('Share the success')}})Copy the code
Vue-based encapsulation
Simply load brige.js
import './bridge'
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
Copy the code
conclusion
- Don’t use UIWebview on ios, use WkWebview.
- Android should be aware of webView memory leaks.
- The front end controls the packaging volume, and webpack is not recommended because it generates a lot of webpack wrapping code.
- It is recommended to use rollup lightweight front-end engineering packaging without generating redundant JS code.
- Multi-page mode is recommended. The Native end uses methods such as pushWindow to transfer the jump right to the Native end.