android和js的交互

本文详细探讨了Android如何调用JS代码,包括通过WebView的loadUrl()和evaluateJavascript()方法,并进行了优缺点对比。同时,讲解了JS如何调用Android代码,利用addJavascriptInterface()、shouldOverrideUrlLoading()以及WebChromeClient的对话框回调方法。建议根据Android版本选择合适的方法进行混合使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android调用JS代码

<script>
// Android需要调用的方法
   function callJS(){
      alert("Android调用了JS的callJS方法");
   }
</script>

通过WebView的loadUrl()

mWebView =(WebView) findViewById(R.id.webview);

WebSettings webSettings = mWebView.getSettings();

// 设置与Js交互的权限
webSettings.setJavaScriptEnabled(true);
// 设置允许JS弹窗
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

// 加载JS代码
mWebView.loadUrl("file:///android_asset/javascript.html");

// 注意调用的JS方法名要对应上
// 调用javascript的callJS()方法
mWebView.loadUrl("javascript:callJS()");  


// 通过设置WebChromeClient对象处理JavaScript的对话框
mWebView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        AlertDialog.Builder b = new AlertDialog.Builder(MainActivity.this);
        b.setTitle("Alert");
        b.setMessage(message);
        b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm();
            }
        });
        b.setCancelable(false);
        b.create().show();
        return true;
    }

});

通过WebView的evaluateJavascript()

mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
    @Override
     public void onReceiveValue(String value) {
        //此处为 js 返回的结果
    }
});

对比

方式优点缺点使用场景
loadUrl()方便简洁效率低,获取返回值麻烦不需要获取返回值,对性能要求低
evaluateJavascript()效率高向下兼容性差Android4.4以上

使用建议

两种方法混合使用,即Android 4.4以下使用方法1,Android 4.4以上方法2

JS调用Android代码

通过 WebView的addJavascriptInterface()进行对象映射

// 继承自Object类
public class AndroidtoJs extends Object {

    // 定义JS需要调用的方法
    // 被JS调用的方法必须加入@JavascriptInterface注解
    @JavascriptInterface
    public void hello(String msg) {
        System.out.println("JS调用了Android的hello方法");
    }
}
<head>
    <meta charset="utf-8">
    <title>Carson</title>  
    <script>
        function callAndroid(){
            //由于对象映射,所以调用test
            对象等于调用Android映射的对象
           test.hello("js调用了android中的hello方法");
        }
    </script>
</head>
<body>
    //点击按钮则调用callAndroid函数
    <button type="button" id="button1" onclick="callAndroid()"></button>
</body>
mWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = mWebView.getSettings();

// 设置与Js交互的权限
webSettings.setJavaScriptEnabled(true);

// 通过addJavascriptInterface()将Java对象映射到JS对象
//参数1:Javascript对象名
//参数2:Java对象名
mWebView.addJavascriptInterface(new AndroidtoJs(), "test");//AndroidtoJS类对象映射到js的test对象

mWebView.loadUrl("file:///android_asset/javascript.html");

通过 WebViewClient 的方法shouldOverrideUrlLoading ()回调拦截 url

// 复写WebViewClient类的shouldOverrideUrlLoading方法
webView.setWebViewClient(
    new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {

            //根据协议的参数,判断是否是
            所需要的url
            // 一般根据scheme(协议格式) &authority(协议名)判断(两
            个参数)
            //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的)

            Uri uri = Uri.parse(url);
            // 如果url的协议 = 预先约定的 js 协议就解析往下解析参数
            if(uri.getScheme().equals("js")) {

                // 如果 authority  = 预先约定协议里的 webview,即代表都符合约定的协议
                //所以拦截url,下面JS开始
                调用Android需要的方法
                if(uri.getAuthority().equals("webview")) {

                    //执行JS所需要调用的
                    逻辑
                                System.out.println("js调用了Android的方法");
                    //可以在协议上带有参
                    数并传递到Android上
                }

                return true;
            }
            return super.shouldOverrideUrlLoading(view, url);
        }
    }
);

通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

// 复写WebChromeClient类的onJsPrompt方法
webView.setWebChromeClient(
    new WebChromeClient() {
        // 拦截输入框
        // 参数message:代表promt()的内容(不是url)
        // 参数result:代表输入框的返回值
        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {

            //根据协议的参数,判断是否是
            所需要的url
            // 一般根据scheme(协议格式) &authority(协议名)判断(两
            个参数)
            //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的)

            Uri uri = Uri.parse(url);
            // 如果url的协议 = 预先约定的 js 协议就解析往下解析参数
            if(uri.getScheme().equals("js")) {

                // 如果 authority  = 预先约定协议里的 webview,即代表都符合约定的协议
                //所以拦截url,下面JS开始
                调用Android需要的方法
                if(uri.getAuthority().equals("webview")) {

                    result.confirm("js调 用了Android的方法成功啦");
                }

                return true;
            }
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }
    }

    // 拦截JS的警告框
    @Override
    public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
        return super.onJsAlert(view, url, message, result);
    }

    // 拦截JS的确认框
    @Override
    public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
        return super.onJsConfirm(view, url, message, result);
    }
);

对比

方式优点缺点使用场景
addJavascriptInterface()添加对象映射方便简洁Android4.2一下存在漏洞Android4.2以上相对简单互调场景
WebViewClient的shouldOverrideUrlLoading()拦截url不存在漏洞问题使用复杂:需要进行协议的约束:从Native往Web层传值比较繁琐不需要返回值情况的互调场景
WebChromeClient的OnJsAlert()、onJsConfirm()、onJsPrompt方法不存在漏洞问题使用复杂:需要进行协议的约束大多数情况下的互调场景

转自:Android:你要的WebView与 JS 交互方式 都在这里了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值