当前位置:网站首页>How does H5 communicate with native apps?
How does H5 communicate with native apps?
2022-06-23 22:14:00 【User 9253515】
Preface
To improve development efficiency , Developers tend to use native app Nested front end inside h5 The rapid development of pages , This is about h5 And native inter calls , Transfer data to each other , Next, make a simple record and share about the interaction mode in the practice project , I don't say much nonsense , Direct to the text :
Thanks to Android and ios It's not the same way , So we have to deal with it separately First, paste the code to judge the access terminal
// Judge the access terminal
function browserVersion(){
var u = navigator.userAgent;
return { trident: u.indexOf('Trident') > -1, //IE kernel presto: u.indexOf('Presto') > -1, //opera kernel webKit: u.indexOf('AppleWebKit') > -1, // Apple 、 Google kernel gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1,// Firefox kernel mobile: !!u.match(/AppleWebKit.*Mobile.*/), // Is it a mobile terminal
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios terminal
android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android terminal iPhone: u.indexOf('iPhone') > -1 , // Is it iPhone perhaps QQHD browser iPad: u.indexOf('iPad') > -1, // whether iPad webApp: u.indexOf('Safari') == -1, // whether web It should be programmed , No head and bottom weixin: u.indexOf('MicroMessenger') > -1, // Wechat or not (2015-01-22 newly added )qq: u.match(/\sQQ/i) == " qq" // whether QQ
};
Understand the principle of communication first webview
IOS Containers stay IOS The client , The first thing we want to mention is a man named UIWebView The container of , Apple introduced him as :
UIWebView Is an object that can load web pages , It has the function of browsing records , And the loaded web page content is programmable . To put it bluntly UIWebView It has browser like functions , We can use it to open the page , And do some customized functions , If you can let js Call a method to get the mobile phone GPS Information .
But it should be noted that ,Safari Browser controls used by the browser and UIwebView Components are not the same , There is a big gap in performance between the two . Fortunately, , Apple released iOS8 When , I added a new one WKWebView Component containers , If your APP Only consider supporting iOS8 And above , Then you can use this new browser control .
WKWebView Reconstruct the original UIWebView Of 14 Classes ,3 Agreements , While improving performance , It gives developers more detailed configuration ( These configurations are for clients only IOS Development , For front-end H5 Come on , It is important to keep the two container invocation methods consistent ).
Android Containers In the Android client ,webView The container is consistent with the browser kernel of the mobile phone , Mostly for android-chrome. There are no compatibility and performance issues .
RN Containers stay react-native In development , from rn 0.37 The version officially introduced components , Call the native browser in Android , stay IOS Is called by default UIWebView Containers . from IOS12 Start , Apple was officially abandoned UIWebView, Unified adoption WKWebView.
RN from 0.57 rise , It can be specified that WKWebView As WebView The implementation of the
// rn js code
<WebView useWebKit={true} source={{ url: 'https://m.douyu.com' }} />
WebView Components should not be nested in or native click components , Can cause H5 Inner page scrolling failure
h5 towards ios Client sends message ;
stay ios in , There is no ready-made api Give Way js To call native Methods , however UIWebView And WKWebView Be able to intercept h5 All network requests initiated within . So our thinking is through h5 Initiate a network request for a specific protocol agreed in , Such as 'jsbridge://bridge2.native?params=' + encodeURIComponent(obj) Then take it with you and pass it on to ios Parameters of ; After the request with the specified protocol header is intercepted in the client, the request is blocked and parsed url Parameters on , Execute the corresponding logic
stay H5 There are two ways to initiate this specific protocol request in :
adopt localtion.href;
adopt location.href There is a problem , That is, if we modify it many times in a row window.location.href Value , stay Native The layer can only receive the last request , All previous requests will be ignored .
adopt iframe The way ;
Use iframe The way , To evoke Native; Take the evocation sharing component as an example
// h5 js code Encapsulate it
function createIframe(url){
var url = 'jsbridge://getShare?title= Share the title &desc= Share description &link=http%3A%2F%2Fwww.douyu.com&cbName=jsCallClientBack';
var iframe = document.createElement('iframe');iframe.style.width = '1px';
iframe.style.height = '1px';
iframe.style.display = 'none';
iframe.src = https://segmentfault.com/a/url;
document.body.appendChild(iframe);
setTimeout(function() {iframe.remove();
}, 100);
}
The client then intercepts the request , And the corresponding methods and parameters are analyzed : Here we use ios For example :
// IOS swift code
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let url = request.URL
let scheme = url?.scheme
let method = url?.host
let query = url?.query
if url != nil && scheme == "jsbridge" { switch method! {case "getShare":
self.getShare()
default:
print("default")}
return false
} else {return true
}
}
If you don't understand, just skip , Non emphasis .....
Here we add cbName=jsCallClientBack, This jsCallClientBack by JS Call the callback function defined by the client , At the business level jsBridge In package , We pass in an anonymous function as a callback , The bottom layer binds this function to window Of jsbridge Object and define a unique key, This key Namely jsCallClientBack, After the client has processed the logic , The method described above will be used to call back window The way to go .
ps: After binding the callback to window Next time , Pay special attention to using bind Keep inside the function this The original direction of is unchanged
IOS Client calls H5 Method
Native call Javascript Language , It's through UIWebView Component's stringByEvaluatingJavaScriptFromString Method to achieve , This method returns js The execution result of the script .
// IOS swift code
webview.stringByEvaluatingJavaScriptFromString("window.methodName()")
From the above code, we can see that it actually implements a string js Code , Called window Next object , If we want to let native To call us js The method of writing , Then this method should be in window You can access . But from the overall point of view , We just expose an object such as JSBridge to native Just call .
The callback function that calls the client's native method will also be bound to window For the client to successfully counter call , In fact, the final result of a single call to a client method is a two-way call to each other .
H5 call Android Client method
On Android webView There are three calls in native The way :
adopt schema The way , Client side usage shouldOverrideUrlLoading Method pair url Request the protocol to parse . such js The method of calling and ios The same as , Use iframe To call native Method . By means of webview The page is directly injected with native js Code mode , Use addJavascriptInterface Method to implement .
// android JAVA code
class JSInterface {
@JavascriptInterface
public String getShare() {//...
return "share";
}
}
webView.addJavascriptInterface(new JSInterface(), "AndroidNativeApi");
The above code is in the page window Objects are injected with AndroidNativeApi object . stay js You can call native methods directly in .
Use prompt,console.log,alert The way , These three methods are right js Li is a native property , stay android webview This layer can override these three methods . Generally we use prompt, Because this is js It's not used much in , For and native Communication side effects are less .
// android JAVA code
class WebChromeClient extends WebChromeClient {
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {// rewrite window Under the prompt, adopt result Return results
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {}
}
Generally speaking, Android clients choose 1、2 One of the schemes to communicate , From the front-end level , It is recommended that all clients use schema The way of agreement , Convenient for front end jsBridge Maintenance and iteration of the underlying code .
Android Client calls H5 Method
On Android APP in , Client pass webview Of loadUrl To call :
// android JAVA code
webView.loadUrl("javascript:window.jsBridge.getShare()");
H5 The client binds the method to window The object under the , There is no need to communicate with IOS Make a distinction
H5 call RN client
We know RN Of webView A component is actually a secondary encapsulation of a native container , So we don't need to go directly through schema Protocol to communicate , Just use the browser postMessage、onMessage To deliver a message , Be similar to iframe, And the real communication process RN It's already done for us .
// h5 js code
window.postMessage(data);
// rn js code
<WebView
ref="webView"
source={require('../html/index.html')} injectedJavaScript={'window.androidConfig = {}'} // Through this props Can be in webView Inject attribute methods during initialization onMessage={e => { let { data } = e.nativeEvent;//...
}}
/>
RN Client calls H5
postMessage It's two-way , So it can also be in RN Inside message ,H5 Receive a message to trigger the corresponding callback
this.refs.webView.postMessage({
cbName: 'xxx',
param: {}});
front end jsBridge Encapsulation
In understanding js After the communication principle with the client bottom , We can IOS、 Android is packaged into jsBridge It is provided to the business layer to develop calls .
class JsBridge {
static lastCallTime
constructor() { if (UA.isReactNative()) { document.addEventListener('message', function(e) {window.jsClientCallBack[e.data.cbName](e.data.param);
});
}
}
// Universal callNtive Method
callClient(functionName, data, callback) {// Avoid continuous calls
if (JsBridge.lastCallTime && (Date.now() - JsBridge.lastCallTime) < 100) { setTimeout(() => {this.callClient(functionName, data, callback);
}, 100);
return;
}
JsBridge.lastCallTime = Date.now();
data = data || {}; if (callback) {const cbName = randomName();
Object.assign(data, { cbName });window.jsClientCallBack[cbName] = callBack.bind(this);
}
if (UA.isIOS()) { data.forEach((key, value) => { try {data[key] = JSON.stringify(value);
} catch(e) { }});
var url = 'jsbridge://' + functionName + '?' parseJSON(data);
var iframe = document.createElement('iframe');iframe.style.width = '1px';
iframe.style.height = '1px';
iframe.style.display = 'none';
iframe.src = url;
document.body.appendChild(iframe);
setTimeout(() => {iframe.remove();
}, 100);
} else if (UA.isAndroid()) { // The Android client uses the second communication method mentioned above window.AndroidNativeApi &&
window.AndroidNativeApi[functionName] &&
window.AndroidNativeApi[functionName](JSON.stringify(data));
} else if (UA.isReactNative()) { //rn Of <webView> Components can be set props.userAgent To make the H5 distinguish window.postMessage(
JSON.stringify(data);
);
} else { console.error(' Not obtained platform Information , Transfer api Failure ');}
}
// Business layer custom methods
getShare(data, callBack) {//..
}
}
On the basis of core encapsulation , We can do more optimization , For example, each callback function is self destructed to release memory after being called
Four 、 debugging
Use the android chrome://inspect debug , Need to climb over the wall IOS Use mac safari Of develop Option to debug Use RN Of http://localhost:8081/debugger-ui Only debugging RN Code , Unable to debug webView Code ,RN Next webView Debugging and corresponding native identical , But in chrome://inspect There will be style problems under . Unless it is pure RN To write , Pack it directly into APP, Otherwise, it is not recommended to RN Call down webView Components
Related courses
Android Basic series of tutorials : Android basic course U- Summary _ Bili, Bili _bilibiliAndroid basic course UI- Layout _ Bili, Bili _bilibiliAndroid basic course UI- Control _ Bili, Bili _bilibiliAndroid basic course UI- Animation _ Bili, Bili _bilibiliAndroid basic course -activity Use _ Bili, Bili _bilibiliAndroid basic course -Fragment Usage method _ Bili, Bili _bilibiliAndroid basic course - Hot repair / The principle of thermal renewal technology _ Bili, Bili _bilibili
In this paper, from https://juejin.cn/post/6885988193402159118, If there is any infringement , Please contact to delete .
边栏推荐
- Bi SQL constraints
- H264_ AVC analysis
- How to realize batch generation of serial number QR code
- Using h5ai to build Download Station
- Take you through the distributed file system
- HR SaaS is finally on the rise
- Devops sharing: how to hold the meeting?
- 什么是股票线上开户?手机开户安全么?
- Interpretation of opentelemetry project
- Flink practical tutorial: advanced 4-window top n
猜你喜欢

ICML2022 | 基于对比学习的离线元强化学习的鲁棒任务表示

CAD图在线Web测量工具代码实现(测量距离、面积、角度等)

Configuring error sets using MySQL for Ubuntu 20.04.4 LTS

北大、加州伯克利大學等聯合| Domain-Adaptive Text Classification with Structured Knowledge from Unlabeled Data(基於未標記數據的結構化知識的領域自適應文本分類)

万字长文!一文搞懂InheritedWidget 局部刷新机制

Sending network request in wechat applet

Leetcode must review six lintcode (28348455116385)

Leetcode algorithm interview sprint sorting algorithm theory (32)

How to use the serial port assistant in STC ISP?

Cloud native practice of meituan cluster scheduling system
随机推荐
How to improve the high concurrency of the server
Environment construction of go language foundation
《阿里云天池大赛赛题解析》——O2O优惠卷预测
HDLBits-&gt;Circuits-&gt;Arithmetic Circuitd-&gt;3-bit binary adder
How does the fortress remote login server operate? What is the application value of Fortress machine?
Notepad++ installing the jsonview plug-in
Detailed explanation of redisson distribution lock
TMUX support, file transfer tool Trz / Tsz (trzsz) similar to RZ / SZ
Start optimization - directed acyclic graph
Meaning of the last seven digits of wider face
The "Star" industry in the small town is escorted by wechat cloud hosting
Sending network request in wechat applet
Assembly deployment process
TDD development mode recommendation process
Ffmpeg for audio and video commands
HR SaaS is finally on the rise
Performance optimization of database 5- database, table and data migration
To develop AI face comparison, how to output multiple faces with comparative similarity?
Question: how to understand the network protocol and why the OSI reference model is divided into seven layers
Peking University, University of California Berkeley and others jointly | domain adaptive text classification with structured knowledge from unlabeled data (Domain Adaptive Text Classification Based o