原生+H5开发之:js交互【location方式】

本文详细介绍了Android与JavaScript通过WebView实现互相调用的方法。包括Android调用JS代码的两种方式及JS调用Android代码的三种方式。展示了具体的代码示例,并讨论了不同交互方式的特点。

1. 交互方式总结

1Android与JS通过WebView互相调用方法,实际上是:

  • Android去调用JS的代码
  • JS去调用Android的代码
    二者沟通的桥梁是WebView

    对于Android调用JS代码的方法有2种: 
    1. 通过WebViewloadUrl() 
    2. 通过WebViewevaluateJavascript()

    对于JS调用Android代码的方法有3种: 
    1. 通过WebViewaddJavascriptInterface()进行对象映射 
    2. 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url 
    3. 通过 WebChromeClient 的onJsAlert()onJsConfirm()onJsPrompt()方法回调拦截JS对话框alert()confirm()prompt() 消息

  • 2.1 Android通过WebView调用 JS 代码

  • mWebView =(WebView) findViewById(R.id.webview);
    mWebView.loadUrl("file:///android_asset/javascript.html");
    LocationActivity.this.webView.post(() -> LocationActivity.this.webView.evaluateJavascript(
                                "javascript:locationDidChange('" + LocationActivity.this.locationString + "')", value -> {
                                    // 此处为 js 返回的结果
                            }));

    2.2 JS通过WebView调用 Android 代码

  • 方式2:通过 WebViewClient 的方法shouldOverrideUrlLoading ()回调拦截 url

  • <!DOCTYPE html>
    <html>
    
       <head>
          <meta charset="utf-8">
          <title>Carson_Ho</title>
    
         <script>
             function callAndroid(){
                /*约定的url协议为:js://webview?arg1=111&arg2=222*/
                document.location = "js://webview?arg1=111&arg2=222";
             }
          </script>
    </head>
    
    <!-- 点击按钮则调用callAndroid()方法  -->
       <body>
         <button type="button" id="button1" οnclick="callAndroid()">点击调用Android代码</button>
       </body>
    </html>
    private class MyWebViewClient extends WebViewClient {
    
            @TargetApi(21)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return this.shouldOverrideUrlLoading(view, request.getUrl().toString());
            }
    
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 步骤2:根据协议的参数,判断是否是所需要的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")) {
                        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + uri.getQueryParameter("tel")));
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        LocationActivity.this.startActivity(intent);
                    } else if (uri.getAuthority().equals("location")) {
    
                        LocationActivity.this.webView.post(() -> LocationActivity.this.webView.evaluateJavascript(
                                "javascript:locationDidChange('" + LocationActivity.this.locationString + "')", value -> {
                                    // 此处为 js 返回的结果
                            }));
    
                    } else if (uri.getAuthority().equals("toast")) {
    
                        Toast.makeText(LocationActivity.this, uri.getQueryParameter("info"), Toast.LENGTH_SHORT).show();
                    } else if (uri.getAuthority().equals("takePhoto")) {
    
                        photoIdent = uri.getQueryParameter("ident");
                        openPopupWindow();
                    } else if (uri.getAuthority().equals("takeVideo")) {
                        /***************************** 录制视频 ***********************************/
                        EventBus.getDefault().post(new VideoIdentEvent(uri.getQueryParameter("ident")));
                        Intent intent = new Intent(LocationActivity.this, VideoActivity.class);
                        intent.putExtra(VideoActivity.VIDEO_IDENT, uri.getQueryParameter("ident"));
                        startActivity(intent);
                    } else if (uri.getAuthority().equals("playVideo")) {
                        /***************************** 播放视频 ***********************************/
                        startActivity(new Intent(LocationActivity.this, VideoPlayerActivity.class).putExtra("path",
                                uri.getQueryParameter("path")));
                    } else if (uri.getAuthority().equals("takeAudio")) {
                        /******************************** 录制音频 ********************************/
                        dialogShow(uri.getQueryParameter("ident"));
                    } else if (org.apache.commons.lang3.StringUtils.equals(uri.getAuthority(), "userLogin")) {
                        /******************************** 登录 ********************************/
                        String username = uri.getQueryParameter("username");
                        if (TextUtils.isEmpty(username)) {
                            return true;
                        }
    
                        JPushInterface.setAlias(LocationActivity.this, username.hashCode(), username);
    
                        String account = uri.getQueryParameter("yx_username");
                        String password = uri.getQueryParameter("yx_password");
    
                        chatFragment.startImLogin(username, account, password);
                    } else if (org.apache.commons.lang3.StringUtils.equals(uri.getAuthority(), "userLogout")) {
                        /******************************** 退出 ********************************/
                        chatFragment.logout();
    
                        finish();
                    } else if (org.apache.commons.lang3.StringUtils.equals(uri.getAuthority(), "playAudio")) {
                        /***************************** 播放视频 ***********************************/
                        MediaActivity.start(LocationActivity.this, uri.getQueryParameter("path"));
                    }
    
                    return true;
                }
    
                return false;
            }

    这种方式的优点就是不存在漏洞,并且稳定

转载于:https://www.cnblogs.com/univalsoft-mobile-team/p/8793394.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值