现在开发移动端应用,方案有很多, 比如native(IOS和Android)、 hybrid和react native等。其中hybrid、react native等方案对前端很友好,毕竟是用我们熟悉的JavaScript开发,但JavaScript无法直接调用native本身提供的能力,比如获取相册信息。所以就需要通过一种方式将native能力提供给JavaScript,同时native也可能需要调用JavaScript的一些功能,而JSBridge就是JavaScript和native之间的桥梁,提供两者相互调用的能力。

依然有很多坑

使用方式:

一、添加依赖(或者导入aar)

implementation 'com.github.lzyzsd:jsbridge:1.0.4'

二、使用 BridgeWebView对象,内部是对webview的封装直接使用就可以

android:id="@+id/webView"

android:layout_width="match_parent"

android:layout_height="match_parent" />

三、声明bridgeWebView实例 初始化

private BridgeWebView bridgeWebView;

bridgeWebView = findViewById(R.id.webView);

四、初始化 - 并且加载url

bridgeWebView.getSettings().setAllowFileAccess(true);

bridgeWebView.getSettings().setAppCacheEnabled(true);

bridgeWebView.getSettings().setDatabaseEnabled(true);

// 允许网页定位

bridgeWebView.getSettings().setGeolocationEnabled(true);

// 允许网页弹对话框

bridgeWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);

// 加快网页加载完成的速度,等页面完成再加载图片

bridgeWebView.getSettings().setLoadsImagesAutomatically(true);

// 开启 localStorage

bridgeWebView.getSettings().setDomStorageEnabled(true);

// 设置支持javascript// 本地 DOM 存储(解决加载某些网页出现白板现象)

bridgeWebView.getSettings().setJavaScriptEnabled(true);

// 进行缩放

bridgeWebView.getSettings().setBuiltInZoomControls(true);

// 设置UserAgent

bridgeWebView.getSettings().setUserAgentString(bridgeWebView.getSettings().getUserAgentString() + "app");

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

// 解决 Android 5.0 上 WebView 默认不允许加载 Http 与 Https 混合内容

bridgeWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

}

bridgeWebView.setWebViewClient(new MyWebViewClient(bridgeWebView));

bridgeWebView.setWebChromeClient(new WebChromeClient());

bridgeWebView.loadUrl("https://xxx.xxx.xxx:8080/h5/");

五、MyWebViewClient类

public class MyWebViewClient extends BridgeWebViewClient {

public MyWebViewClient(BridgeWebView webView) {

super(webView);

}

@SuppressLint("WebViewClientOnReceivedSslError")

@Override

public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {

//super.onReceivedSslError(view, handler, error);

// 如何处理应用中的 WebView SSL 错误处理程序提醒

handler.proceed();

}

/**

* 同名 API 兼容

*/

@TargetApi(Build.VERSION_CODES.M)

@Override

public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {

if (request.isForMainFrame()) {

onReceivedError(view,

error.getErrorCode(), error.getDescription().toString(),

request.getUrl().toString());

}

}

/**

* 加载错误

*/

@Override

public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

super.onReceivedError(view, errorCode, description, failingUrl);

}

/**

* 同名 API 兼容

*/

@TargetApi(Build.VERSION_CODES.N)

@Override

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {

return shouldOverrideUrlLoading(view, request.getUrl().toString());

}

/**

* 跳转到其他链接

*/

// @Override

// public boolean shouldOverrideUrlLoading(WebView view, String url) {

// Log.i("WebView shouldOverrideUrlLoading:%s", url);

// String scheme = Uri.parse(url).getScheme();

// if (scheme == null) {

// return false;

// }

// switch (scheme) {

// // 如果这是跳链接操作

// case "http":

// case "https":

// view.loadUrl(url);

// break;

// // 如果这是打电话操作

// case "tel":

dialing(view, url);

// break;

// default:

// break;

// }

// return true;

// }

}

六、初始化Android接收Hanlers

// 设置默认接收函数 并返回数据

bridgeWebView.setDefaultHandler(new BridgeHandler() {

@Override

public void handler(String data, CallBackFunction function) {

function.onCallBack("返回给H5的数据");

}

});

七、H5(uniappVue)端代码

       在utils目录下新建js,名字叫 jsBridge

/**

* 使用 JSBridge 总结:

* 1、跟 IOS 交互的时候,只需要且必须注册 iosFuntion 方法即可,

* 不能在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,否则 IOS 无法调用到 H5 的注册函数;

* 2、与安卓进行交互的时候

* ①、使用 iosFuntion,就可以实现 H5 调用 安卓的注册函数,但是安卓无法调用 H5 的注册函数,

* 并且 H5 调用安卓成功后的回调函数也无法执行

* ②、使用 andoirFunction 并且要在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,

* 安卓才可以正常调用 H5 的回调函数,并且 H5 调用安卓成功后的回调函数也可以正常执行了

*/

const u = navigator.userAgent;

// Android终端

const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;

// IOS 终端

const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);

/**

* Android 与安卓交互时:

* 1、不调用这个函数安卓无法调用 H5 注册的事件函数;

* 2、但是 H5 可以正常调用安卓注册的事件函数;

* 3、还必须在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,否则:

* ①、安卓依然无法调用 H5 注册的事件函数

* ①、H5 正常调用安卓事件函数后的回调函数无法正常执行

*

* @param {*} callback

*/

const andoirFunction = (callback) => {

if (window.WebViewJavascriptBridge) {

callback(window.WebViewJavascriptBridge);

} else {

document.addEventListener('WebViewJavascriptBridgeReady', function () {

callback(window.WebViewJavascriptBridge);

}, false)

}

}

/**

* IOS 与 IOS 交互时,使用这个函数即可,别的操作都不需要执行

* @param {*} callback

*/

const iosFuntion = (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);

}

/**

* 注册 setupWebViewJavascriptBridge 方法

* 之所以不将上面两个方法融合成一个方法,是因为放在一起,那么就只有 iosFuntion 中相关的方法体生效

*/

window.setupWebViewJavascriptBridge = isAndroid ? andoirFunction : iosFuntion;

/**

* 这里如果不做判断是不是安卓,而是直接就执行下面的方法,就会导致

* 1、IOS 无法调用 H5 这边注册的事件函数

* 2、H5 可以正常调用 IOS 这边的事件函数,并且 H5 的回调函数可以正常执行

*/

if (isAndroid) {

/**

* 与安卓交互时,不调用这个函数会导致:

* 1、H5 可以正常调用 安卓这边的事件函数,但是无法再调用到 H5 的回调函数

*

* 前提 setupWebViewJavascriptBridge 这个函数使用的是 andoirFunction 这个,否则还是会导致上面 1 的现象出现

*/

window.setupWebViewJavascriptBridge(function (bridge) {

// 注册 H5 界面的默认接收函数(与安卓交互时,不注册这个事件无法接收回调函数)

bridge.init(function (msg, responseCallback) {

message.success(msg);

responseCallback("JS 返回给原生的消息内容");

})

})

};

八、main.js 加入

import jsBridge from './utils/jsBridge'

Vue.prototype.$jsBridge = jsBridge

九、H5页面调用

methods: {

/**

* jsbridge监听native传递数据

*/

aaa() {

// window.setupWebViewJavascriptBridge(bridge => {

// bridge.callHandler('changeUser', 'H5修改appUser值', () => {

// app.globalData.toast('修改好了')

// setUser('bbb');

// });

// })

window.setupWebViewJavascriptBridge(bridge => {

bridge.send("JS 测试传递给原生的消息", (data) => {

app.globalData.toast(data)

console.log(data)

})

})

},

}

十、Android 发送数据给 H5页面 callHandler

mWebView.callHandler("getMessage", "我是android的数据666", new CallBackFunction() {

@Override

public void onCallBack(String data) {

ToastUtils.showShort("我是回掉"+data);

}

});

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: