This article detailed how to use JSBridge to interact with H5 and native Android and IOS. OC and Swift are available on IOS, and Java and Kotlin are available on Android.
First, write first
This article mainly describes how to use JSBridge to communicate between H5 and native through code. The article contains H5, IOS, Android three parts of the code. OC and Swift were used to implement the code respectively in IOS. Android using Java and Kotlin code implementation respectively.
Demo address: jsbridge-example
JSBridgeH5
:H5
End code implementationJSBridgeIOSOC
: nativeIOS
端OC
Code implementationJSBridgeIOSSwift
: nativeIOS
端Swift
Code implementationJSBridgeAndroidJava
: nativeAndroid
端Java
Code implementationJSBridgeAndroidKotlin
: nativeIOS
端Kotlin
Code implementation
This article does not explain the principle of the part, just detailed use of the code to introduce the use of JSBridge. For those who want to know more about the principles, you can search a separate blog about the principles.
Ii. H5 end code
- Initialize the
WebViewJavascriptBridge
, the mode code is as follows - Register event functions for native invocation:
window.setupWebViewJavascriptBridge(bridge => bridge.registerHandler('fnName', function) )
- Call the native event function:
window.setupWebViewJavascriptBridge(bridge => bridge.callHandler('fnName', data, callback) )
1. InitializationWebViewJavascriptBridge
In the project entry file or root js file, add the following code:
// Use the mobile terminal's native userAgent to determine whether it is Android or ios
const u = navigator.userAgent;
/ / Android terminal
const isAndroid = u.indexOf('Android') > - 1 || u.indexOf('Adr') > - 1;
/ / IOS terminal
constisIOS = !! u.match(/\(i[^;] +; ( U;) ? CPU.+Mac OS X/);
/** * Init method used with IOS */
const iosFunction = (callback) = > {
if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge) }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback) }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function(){
document.documentElement.removeChild(WVJBIframe);
}, 0);
}
/** * The initialization method for Android */
const androidFunction = (callback) = > {
if (window.WebViewJavascriptBridge) {
callback(window.WebViewJavascriptBridge);
} else {
document.addEventListener('WebViewJavascriptBridgeReady'.function () {
callback(window.WebViewJavascriptBridge);
}, false)}}window.setupWebViewJavascriptBridge = isAndroid ? androidFunction : iosFunction;
isAndroid && window.setupWebViewJavascriptBridge(function (bridge) {
// Register the default receiving function of H5 interface (when interacting with Android, android can send data directly without calling the function name, and can receive data here)
bridge.init(function (msg, responseCallback) {
console.log(msg);
responseCallback("JS returns to native message content"); })});Copy the code
Register event functions that interact with the native
/ * window. SetupWebViewJavascriptBridge (bridge = > {bridge. RegisterHandler (' event function name, fun executive function); }) * /
window.setupWebViewJavascriptBridge(bridge= > {
/** * data: native data * fn: native callback */
bridge.registerHandler("H5Function", (data, fn) => {
console.log(data);
fn && fn();
});
});
Copy the code
3. Call the natively registered event function
The native registered time function is called with the following code:
/ * window. SetupWebViewJavascriptBridge (bridge = > {bridge. CallHandler (' AnZhuoDuan function name, "data" to the native, the callback callback function); }) * /
window.setupWebViewJavascriptBridge(bridge= > {
bridge.callHandler('changeData', data, (result) => {
console.log(result);
});
})
Copy the code
Iii. IOS code
-
Initialize WebViewJavascriptBridge:
+ (instancetype)bridgeForWebView:(id)webView; + (instancetype)bridge:(id)webView; Copy the code
-
– (void)registerHandler:(NSString*)handlerName Handler:(WVJBHandler) Handler;
-
Call the h5-side event function:
- (void)callHandler:(NSString*)handlerName; - (void)callHandler:(NSString*)handlerName data:(id)data; - (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback; Copy the code
1. Introduce WebViewJavascriptBridge
Direct use mode
-
Download WebViewJavascriptBridge
-
Find the WebViewJavascriptBridge folder and drag it directly into the XCode project. In the pop-up window prompted, select Copy items if needed and Create groups, as shown below:
-
The ViewController. H header file into # import “WebViewJavascriptBridge. H
Cocopad usage mode
If you must use this method, Google it yourself.
2. Initialize the WebViewJavascriptBridge
// Enable WebViewJavascriptBridge Log
[WebViewJavascriptBridge enableLogging];
Initialize the WKWebViewConfiguration object
self.webConfig = [[WKWebViewConfiguration alloc] init];
// Set preferences
_webConfig.preferences = [[WKPreferences alloc] init];
// Default is 0
_webConfig.preferences.minimumFontSize = 10;
// The default is YES
_webConfig.preferences.javaScriptEnabled = YES;
// On iOS, the default value is NO, indicating that the window cannot be opened automatically
_webConfig.preferences.javaScriptCanOpenWindowsAutomatically = NO;
// TODO:Replace with the url of the page
NSString *URLSTR = @"http://xxx.xxx.xxx.xx:xxxx";
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:_webConfig];
// Set the UserAgent suffix
_webView.customUserAgent = [NSString stringWithFormat:self.webView.customUserAgent, @"app"];
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
NSURL *url = [NSURL URLWithString:URLSTR];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[_webView loadRequest:urlRequest];
[self.view addSubview:_webView];
self.bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];
[_bridge setWebViewDelegate:self];
Copy the code
3. Register event functions that interact with H5
// Example: Register the changeUser function that changes the User name
[self.bridge registerHandler:@"changeUser" handler:^(id data, WVJBResponseCallback responseCallback) {
// Handle the logic here
NSLog(@"Data from JS %@", data);
if (responseCallback) {
// Execute the callback function
responseCallback(@"Data returned to JS"); }}];Copy the code
4. Call the h5-side event function
[self.bridge callHandler:@"changeName" data:name responseCallback:^(id responseData) {self.bridge callHandler:@"changeName" data:name responseCallback:^(id responseData) { NSLog(responseData);}];Copy the code
Iv. Android code
- Registration and
H5
Interactive event functions:public void registerHandler(String handlerName, BridgeHandler handler) { if(handler ! =null) { messageHandlers.put(handlerName, handler); }}Copy the code
- call
H5
End event functionpublic void callHandler(String handlerName, String data, CallBackFunction callBack) { doSend(handlerName, data, callBack); } Copy the code
- Registration and
H5
The default event for the interaction, i.eH5
End does not call the function name, directly usesend
Function to pass data, and Android can also receive data in this event// Set the default receiver function public void setDefaultHandler(BridgeHandler handler) { this.defaultHandler = handler; } Copy the code
- Call the default event function registered on the H5 side
@Override public void send(String data, CallBackFunction responseCallback) { doSend(null, data, responseCallback); } Copy the code
1. Introduce BridgeWebView
- Add the following code to your project’s build.gradle file:
buildTypes { // ... repositories { // ... maven { url "https://jitpack.io"}}}Copy the code
- Add dependencies:
Implementation 'com. Making. Lzyzsd: jsbridge: 1.0.4'
2. Initialize BridgeWebView
inactivity_main.xml
Add layout to file
<com.github.lzyzsd.jsbridge.BridgeWebView
android:id="@+id/main_wv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.github.lzyzsd.jsbridge.BridgeWebView>
Copy the code
Initialize the BridgeWebView in MainActivity
mWebView = findViewById(R.id.main_wv);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setDatabaseEnabled(true);
/ / open localStorage
mWebView.getSettings().setDomStorageEnabled(true);
// Set javascript support
mWebView.getSettings().setJavaScriptEnabled(true);
// Zoom
mWebView.getSettings().setBuiltInZoomControls(true);
/ / set the UserAgent
mWebView.getSettings().setUserAgentString(mWebView.getSettings().getUserAgentString() + "app");
// Set it to display directly in the current WebView without opening in the system browser
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.setWebViewClient(new MyWebViewClient(mWebView));
mWebView.loadUrl(URL);
Copy the code
3. Register event functions that interact with H5
// The default event function
mWebView.setDefaultHandler(new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Toast.makeText(MainActivity.this, data, Toast.LENGTH_LONG).show();
function.onCallBack("Message content returned by Android to JS"); }});// A normal event function
mWebView.registerHandler("reloadUrl".new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
mWebView.reload();
Toast.makeText(MainActivity.this."Refresh successful ~", Toast.LENGTH_SHORT).show();
function.onCallBack(""); }});Copy the code
4. Call the h5-side event function
// Call the h5-side default event function
mWebView.send("Android message to JS".new CallBackFunction() {
@Override
public void onCallBack(String data) {
Toast.makeText(MainActivity.this, data, Toast.LENGTH_LONG).show(); }});// Call the h5-side normal event function
mWebView.callHandler("changeName", mEditName.getText().toString(), new CallBackFunction() {
@Override
public void onCallBack(String data) {
Toast.makeText(MainActivity.this."Name changed successfully", Toast.LENGTH_SHORT).show();
mEditName.setText(""); }});Copy the code
5. Add network permissions
Now, this step is required, otherwise, the WebView does not load, and the phone screen says Webpage not available.
-
In the androidmanifest.xml manifest file add:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> Copy the code
-
Add the permissions, web pages load may be not to come out, may be because the mistrust of unencrypted traffic, in AndroidManifest. An attribute is added to the application of XML: android: usesCleartextTraffic = “true”. As follows:
<?xml version="1.0" encoding="utf-8"? > <manifest .> <application . android:usesCleartextTraffic="true">.</application> </manifest> Copy the code
Five, the Tips
1. Use WebViewJavascriptBridge in Swift
Just like in OC, drag the downloaded WebViewJavascriptBridge folder directly into the Swift project. However, it cannot be used directly at this point because WebViewJavascriptBridge is written using OC. So you need to create a Header file called: project-name-bridge-header. h to import the OC Header files you need to use. Instead of creating it manually, LET XCode do it for you. Create an OC file in Swift project:
XCode will then automatically prompt you to create the Bridging Header:
Introducing WebViewJavascriptBridge created, in the folder. H header file:
Finally, you can use the methods written in OC normally in Swift code:
Unknown Class ViewController in Interface Builder file Unknown Class ViewController in Interface Builder file
The solution: Open the main. storyboard file and use the following image to find the ViewController in the input box indicated by the arrow, delete it, and then type again. Find a new ViewController and fill it in:
6. Reference links
- JsBridge
- WebViewJavascriptBridge
- IOS developer -WKWebView sets cookies
- OC/C method is used in SWIFT project
- IOS is similar to toast on Android
7. Demo address
jsbridge-example
If it helps, welcome Star!