JSBridge协议实现原生Native、Web双向通信

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在Android开发的过程中,常常需要使用webview加载web界面的情况,JSBridge协议就为Android的原生内部端和web端提供了很好的沟通桥梁。

一、JSBridge是什么?

JSBridge其实就是一种原生Native端和Web端达成的双向通信协议,类似与C/S客户端和服务器的HTTP/HTTPS协议,有了JSBridge协议,Webview组件才能更好的和Web页面进行通信。

二、Web端调用Native端

Web调用Native端的实现方式主要有两种:

1.Native端拦截Webview页面请求的URL Schema.
2.向Webview中注入JSAPI

1.Native端拦截Webview页面请求的URL Schema.

拦截流程如下图:
在这里插入图片描述
下面举个例子:
在web端输入内容,然后通过调用原生的弹窗来展示这个内容.

首先在web设置一个时间监听器,用来监听DOM的加载,然后为按钮showBtn设置一个点击事件,接着在下面实现一个方法用来调用Native端的弹窗方法,调用形式为URL Schema.

Web端代码如下:

<script>
    document.addEventListener('DOMContentLoaded', e => {
        const editText = document.querySelector('#editText');
        const showBtn = document.querySelector('#showBtn');
        showBtn.addEventListener('click', e => {
            const inputValue = editText.value;
        showNativeDialog(inputValue)
        })
    })
    function showNativeDialog(content) {
        window.alert('jsbridge://showNativeDialog?content=' + content);
    }
</script>

接着在Native端实现URL Schema的拦截函数,和Native端的窗口弹窗方法

Native端代码如下:
自定义实现拦截函数MyWebChromeClient:

//自定义WebChromeClient拦截自定义的URL Schema
    private class MyWebChromeClient extends WebChromeClient{
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            if (!message.startsWith("jsbridge://")){
                return super.onJsAlert(view, url, message, result);
            }
            String content = message.substring(message.indexOf("=")+1);
            showNativeDialog(content);
            result.confirm();
            return true;
        }
    }

封装窗口弹窗方法:

//Web端调用原生端方法
private void showNativeDialog(String content){
    new AlertDialog.Builder(this)
            .setTitle("Web端调用Native端")
            .setMessage(content)
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            })
            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            })
            .create()
            .show();
}

2.向Webview中注入JSAPI

注入流程图如下:
在这里插入图片描述
原生Native通过将Java接口注入到Webview中,在Webview中暴露出一个JS对象,JS对象名和java方法命名都是一样的,Web端就可以直接引用这个暴露的全局JS对象,通过调用JS的对象名,直接可以调用Native端的java方法.

下面举个例子:
使用WebView的addJavascriptInterface(Object object, String name)方法来暴露全局的js对象,需要传入一个java对象和需要暴露的js对象的方法名,所以这里写一个内部类,就是需要暴露的js对象及相关的方法:

class NativeBridge {
        private Context mContext;
 
        NativeBridge(Context context) {
            this.mContext = context;
        }
 
        //注意必须加这个注解
        @JavascriptInterface
        public void showNativeDialog(String content) {
            new AlertDialog.Builder(mContext)
                    .setTitle("Web端调用Native端")
                    .setMessage(content)
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    })
                    .create()
                    .show();
        }
    }

将java对象添加到addJavascripInterface对象中去,暴露出一个NativeBridge的JS对象.

mWebview.addJavascriptInterface(new NativeBridge(this), "NativeBridge");

Web端代码如下:

给文档添加事件监听,给按钮添加点击事件,获取输入框的值,最后调用封装的原生方法:

<script>
    window.showWebDialog = content => window.alert(content);
    document.addEventListener('DOMContentLoaded', e => {
        const editText = document.querySelector('#editText');
        const showBtn = document.querySelector('#showBtn');
        showBtn.addEventListener('click', e => {
            const inputValue = editText.value;
        showNativeDialog(inputValue)
        })
    })
    function showNativeDialog(content) {
        window.NativeBridge.showNativeDialog(content);
    }
</script>

三、Native端调用Web端

1.Webview中执行JS代码调用Web端

调用流程图如下:
在这里插入图片描述
在Native端输入内容后,调用Web页面弹窗

Native端代码如下:
开启Webview支持JS脚本开关

mWebview.getSettings().setJavaScriptEnabled(true);

封装一个方法用来接受Native端内容,然后执行JS脚本,调用Web页面弹窗.

//Native端调用Web端方法,只有一种方式,直接执行js代码
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void showWebDialog(String content){
    String jsCode = String.format("window.showWebDialog('%s')",content);
    mWebview.evaluateJavascript(jsCode,null);
}

Native端添加点击事件,用于添加内容到封装方法.

case R.id.mShowBtn://点击按钮获取输入框值,并传入对应的调用Web端的方法中
    showWebDialog(mEditText.getText().toString().trim());
break;

Web端代码如下:
在Web端的showWebDialog方法中调用window展示:

<script>
    window.showWebDialog = content => window.alert(content);
</script>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值