当前位置:   article > 正文

Android-jsbridge基本使用(H5&uniappVue端 双向通信Android&IOS)_android jsbridge

android jsbridge

现在开发移动端应用,方案有很多, 比如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的封装直接使用就可以

  1. <com.github.lzyzsd.jsbridge.BridgeWebView
  2. android:id="@+id/webView"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent" />

三、声明bridgeWebView实例 初始化

  1. private BridgeWebView bridgeWebView;
  2. bridgeWebView = findViewById(R.id.webView);

四、初始化 - 并且加载url

  1. bridgeWebView.getSettings().setAllowFileAccess(true);
  2. bridgeWebView.getSettings().setAppCacheEnabled(true);
  3. bridgeWebView.getSettings().setDatabaseEnabled(true);
  4. // 允许网页定位
  5. bridgeWebView.getSettings().setGeolocationEnabled(true);
  6. // 允许网页弹对话框
  7. bridgeWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
  8. // 加快网页加载完成的速度,等页面完成再加载图片
  9. bridgeWebView.getSettings().setLoadsImagesAutomatically(true);
  10. // 开启 localStorage
  11. bridgeWebView.getSettings().setDomStorageEnabled(true);
  12. // 设置支持javascript// 本地 DOM 存储(解决加载某些网页出现白板现象)
  13. bridgeWebView.getSettings().setJavaScriptEnabled(true);
  14. // 进行缩放
  15. bridgeWebView.getSettings().setBuiltInZoomControls(true);
  16. // 设置UserAgent
  17. bridgeWebView.getSettings().setUserAgentString(bridgeWebView.getSettings().getUserAgentString() + "app");
  18. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  19. // 解决 Android 5.0 上 WebView 默认不允许加载 Http 与 Https 混合内容
  20. bridgeWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
  21. }
  22. bridgeWebView.setWebViewClient(new MyWebViewClient(bridgeWebView));
  23. bridgeWebView.setWebChromeClient(new WebChromeClient());
  24. bridgeWebView.loadUrl("https://xxx.xxx.xxx:8080/h5/");

五、MyWebViewClient类

  1. public class MyWebViewClient extends BridgeWebViewClient {
  2. public MyWebViewClient(BridgeWebView webView) {
  3. super(webView);
  4. }
  5. @SuppressLint("WebViewClientOnReceivedSslError")
  6. @Override
  7. public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
  8. //super.onReceivedSslError(view, handler, error);
  9. // 如何处理应用中的 WebView SSL 错误处理程序提醒
  10. handler.proceed();
  11. }
  12. /**
  13. * 同名 API 兼容
  14. */
  15. @TargetApi(Build.VERSION_CODES.M)
  16. @Override
  17. public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
  18. if (request.isForMainFrame()) {
  19. onReceivedError(view,
  20. error.getErrorCode(), error.getDescription().toString(),
  21. request.getUrl().toString());
  22. }
  23. }
  24. /**
  25. * 加载错误
  26. */
  27. @Override
  28. public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
  29. super.onReceivedError(view, errorCode, description, failingUrl);
  30. }
  31. /**
  32. * 同名 API 兼容
  33. */
  34. @TargetApi(Build.VERSION_CODES.N)
  35. @Override
  36. public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
  37. return shouldOverrideUrlLoading(view, request.getUrl().toString());
  38. }
  39. /**
  40. * 跳转到其他链接
  41. */
  42. // @Override
  43. // public boolean shouldOverrideUrlLoading(WebView view, String url) {
  44. // Log.i("WebView shouldOverrideUrlLoading:%s", url);
  45. // String scheme = Uri.parse(url).getScheme();
  46. // if (scheme == null) {
  47. // return false;
  48. // }
  49. // switch (scheme) {
  50. // // 如果这是跳链接操作
  51. // case "http":
  52. // case "https":
  53. // view.loadUrl(url);
  54. // break;
  55. // // 如果这是打电话操作
  56. // case "tel":
  57. dialing(view, url);
  58. // break;
  59. // default:
  60. // break;
  61. // }
  62. // return true;
  63. // }
  64. }

六、初始化Android接收Hanlers

  1. // 设置默认接收函数 并返回数据
  2. bridgeWebView.setDefaultHandler(new BridgeHandler() {
  3. @Override
  4. public void handler(String data, CallBackFunction function) {
  5. function.onCallBack("返回给H5的数据");
  6. }
  7. });

七、H5(uniappVue)端代码

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

  1. /**
  2. * 使用 JSBridge 总结:
  3. * 1、跟 IOS 交互的时候,只需要且必须注册 iosFuntion 方法即可,
  4. * 不能在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,否则 IOS 无法调用到 H5 的注册函数;
  5. * 2、与安卓进行交互的时候
  6. * ①、使用 iosFuntion,就可以实现 H5 调用 安卓的注册函数,但是安卓无法调用 H5 的注册函数,
  7. * 并且 H5 调用安卓成功后的回调函数也无法执行
  8. * ②、使用 andoirFunction 并且要在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,
  9. * 安卓才可以正常调用 H5 的回调函数,并且 H5 调用安卓成功后的回调函数也可以正常执行了
  10. */
  11. const u = navigator.userAgent;
  12. // Android终端
  13. const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
  14. // IOS 终端
  15. const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
  16. /**
  17. * Android 与安卓交互时:
  18. * 1、不调用这个函数安卓无法调用 H5 注册的事件函数;
  19. * 2、但是 H5 可以正常调用安卓注册的事件函数;
  20. * 3、还必须在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,否则:
  21. * ①、安卓依然无法调用 H5 注册的事件函数
  22. * ①、H5 正常调用安卓事件函数后的回调函数无法正常执行
  23. *
  24. * @param {*} callback
  25. */
  26. const andoirFunction = (callback) => {
  27. if (window.WebViewJavascriptBridge) {
  28. callback(window.WebViewJavascriptBridge);
  29. } else {
  30. document.addEventListener('WebViewJavascriptBridgeReady', function () {
  31. callback(window.WebViewJavascriptBridge);
  32. }, false)
  33. }
  34. }
  35. /**
  36. * IOS 与 IOS 交互时,使用这个函数即可,别的操作都不需要执行
  37. * @param {*} callback
  38. */
  39. const iosFuntion = (callback) => {
  40. if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge) }
  41. if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback) }
  42. window.WVJBCallbacks = [callback];
  43. var WVJBIframe = document.createElement('iframe');
  44. WVJBIframe.style.display = 'none';
  45. WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
  46. document.documentElement.appendChild(WVJBIframe);
  47. setTimeout(function(){
  48. document.documentElement.removeChild(WVJBIframe);
  49. }, 0);
  50. }
  51. /**
  52. * 注册 setupWebViewJavascriptBridge 方法
  53. * 之所以不将上面两个方法融合成一个方法,是因为放在一起,那么就只有 iosFuntion 中相关的方法体生效
  54. */
  55. window.setupWebViewJavascriptBridge = isAndroid ? andoirFunction : iosFuntion;
  56. /**
  57. * 这里如果不做判断是不是安卓,而是直接就执行下面的方法,就会导致
  58. * 1、IOS 无法调用 H5 这边注册的事件函数
  59. * 2、H5 可以正常调用 IOS 这边的事件函数,并且 H5 的回调函数可以正常执行
  60. */
  61. if (isAndroid) {
  62. /**
  63. * 与安卓交互时,不调用这个函数会导致:
  64. * 1、H5 可以正常调用 安卓这边的事件函数,但是无法再调用到 H5 的回调函数
  65. *
  66. * 前提 setupWebViewJavascriptBridge 这个函数使用的是 andoirFunction 这个,否则还是会导致上面 1 的现象出现
  67. */
  68. window.setupWebViewJavascriptBridge(function (bridge) {
  69. // 注册 H5 界面的默认接收函数(与安卓交互时,不注册这个事件无法接收回调函数)
  70. bridge.init(function (msg, responseCallback) {
  71. message.success(msg);
  72. responseCallback("JS 返回给原生的消息内容");
  73. })
  74. })
  75. };

八、main.js 加入

  1. import jsBridge from './utils/jsBridge'
  2. Vue.prototype.$jsBridge = jsBridge

九、H5页面调用

  1. methods: {
  2. /**
  3. * jsbridge监听native传递数据
  4. */
  5. aaa() {
  6. // window.setupWebViewJavascriptBridge(bridge => {
  7. // bridge.callHandler('changeUser', 'H5修改appUser值', () => {
  8. // app.globalData.toast('修改好了')
  9. // setUser('bbb');
  10. // });
  11. // })
  12. window.setupWebViewJavascriptBridge(bridge => {
  13. bridge.send("JS 测试传递给原生的消息", (data) => {
  14. app.globalData.toast(data)
  15. console.log(data)
  16. })
  17. })
  18. },
  19. }

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

  1. mWebView.callHandler("getMessage", "我是android的数据666", new CallBackFunction() {
  2. @Override
  3. public void onCallBack(String data) {
  4. ToastUtils.showShort("我是回掉"+data);
  5. }
  6. });

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/561978
推荐阅读
相关标签
  

闽ICP备14008679号