当前位置:网站首页>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 .
边栏推荐
- Digital transformation solution for supply chain platform of mechanical equipment industry
- BenchCLAMP:评估语义分析语言模型的基准
- After CVM is configured with IPv6, it cannot be accessed as IPv6 or cannot access IPv6 sites
- Environment construction of go language foundation
- University of North China, Berkeley University of California, etc. | Domain Adaptive Text Classification with structural Knowledge from unlabeled data
- there can be only one auto column and it must be defined as a key
- Detailed explanation of lkadoc interface tool
- Tencent cloud database tdsql elite challenge Q & A (real-time update)
- How API gateway extends the importance of gateway extension
- Use bcryptjs to encrypt the password
猜你喜欢

Leetcode must review six lintcode (28348455116385)

University of North China, Berkeley University of California, etc. | Domain Adaptive Text Classification with structural Knowledge from unlabeled data

Experiment 5 module, package and Library

Code implementation of CAD drawing online web measurement tool (measuring distance, area, angle, etc.)

Code implementation of CAD drawing online web measurement tool (measuring distance, area, angle, etc.)

MySQL de duplication query only keeps one latest record

Using the provider to transform the shit like code, the amount of code is reduced by 2/3!

How to improve the content quality of short video, these four elements must be achieved

Sending network request in wechat applet

万字长文!一文搞懂InheritedWidget 局部刷新机制
随机推荐
《阿里云天池大赛赛题解析》——O2O优惠卷预测
CAD图在线Web测量工具代码实现(测量距离、面积、角度等)
New high-speed random graph API interface, the first sci-fi graph API interface
Flink practical tutorial: advanced 4-window top n
Leetcode must review six lintcode (28348455116385)
什么是股票线上开户?手机开户安全么?
Sending network request in wechat applet
How does the hybrid cloud realize the IP sec VPN cloud networking dedicated line to realize the interworking between the active and standby intranet?
How to improve the high concurrency of the server
Detailed explanation of lkadoc interface tool
CMU博士论文 | 通过记忆的元强化学习,118页pdf
Tencent cloud server ubuntu18 installs MySQL and logs in remotely
Introduction to scikit learn machine learning practice
How to realize batch generation of serial number QR code
[open source]goravel, a fully functional and extensible golang web application framework
How to do API gateway routing? What are the other functions of API gateway?
BenchCLAMP:评估语义分析语言模型的基准
Detailed explanation of logical structure, physical structure and data operation
What is zero copy?
德国弗莱堡大学、希尔德斯海姆大学等联合 | Zero-Shot AutoML with Pretrained Models(基于预训练模型的零样本AutoML)