美文网首页
WebView与JS交互

WebView与JS交互

作者: 沈溺_16e5 | 来源:发表于2019-05-13 23:36 被阅读0次

    1、交互方式总结

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

    2、Android调用JS

    • 方式1:通过WebView的loadUrl()
      JS代码:
    // JS代码
    <script>
    // Android需要调用的方法
       function callJS(){
          alert("Android调用了JS的callJS方法");
       }
    </script>
    

    Android代码:

    // 注意调用的JS方法名要对应上
    // 调用javascript的callJS()方法                 
    mWv.loadUrl("javascript:callJs('" + mMsg + "')");
    

    完整代码:

    public class MainActivity extends AppCompatActivity {
        WebView mWebView;
        Button button;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mWebView =(WebView) findViewById(R.id.webview);
            WebSettings webSettings = mWebView.getSettings();
            // 设置与Js交互的权限
            webSettings.setJavaScriptEnabled(true);
            // 设置允许JS弹窗
            webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
            // 先载入JS代码
            // 格式规定为:file:///android_asset/文件名.html
            mWebView.loadUrl("file:///android_asset/javascript.html");
            button = (Button) findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 通过Handler发送消息
                    mWebView.post(new Runnable() {
                        @Override
                        public void run() {
                            // 注意调用的JS方法名要对应上
                            // 调用javascript的callJS()方法
                            mWebView.loadUrl("javascript:callJS()");
                        }
                    });
                }
            });
            // 由于设置了弹窗检验调用结果,所以需要支持js对话框
            // webview只是载体,内容的渲染需要使用webviewChromClient类去实现
            // 通过设置WebChromeClient对象处理JavaScript的对话框
            //设置响应js 的Alert()函数
            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;
                }
            });
        }
    }
    
    特别注意:JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用。
    • 方式2:通过WebView的evaluateJavascript()
      优点:该方法比第一种方法效率更高、使用更简洁。
      因为该方法的执行不会使页面刷新,而第一种方法(loadUrl )的执行则会。
      Android 4.4 后才可使用
    // 只需要将第一种方法的loadUrl()换成下面该方法即可
    mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                //此处为 js 返回的结果
            }
        });
    }
    
    0.5252186051721934.png

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

    // Android版本变量
    final int version = Build.VERSION.SDK_INT;
    // 因为该方法在 Android 4.4 版本才可使用,所以使用时需进行版本判断
    if (version < 18) {
        mWebView.loadUrl("javascript:callJS()");
    } else {
        mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                //此处为 js 返回的结果
            }
        });
    }
    

    3、JS通过WebView调用 Android 代码

    • 方式1:通过 WebView的addJavascriptInterface()进行对象映射
      步骤1:定义一个与JS对象映射关系的Android类:AndroidtoJs
    // 继承自Object类
    public class AndroidtoJs extends Object {
        // 定义JS需要调用的方法
        // 被JS调用的方法必须加入@JavascriptInterface注解
        @JavascriptInterface
        public void hello(String msg) {
            System.out.println("JS调用了Android的hello方法");
        }
    }
    

    步骤2:将需要调用的JS代码以.html格式放到src/main/assets文件夹里

    <script>
         function callAndroid(){
         // 由于对象映射,所以调用test对象等于调用Android映射的对象
            window.test.hello("js调用了android中的hello方法");
         }
    </script>
    

    步骤3:在Android里通过WebView设置Android类与JS代码的映射

            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对象
            // 加载JS代码
            // 格式规定为:file:///android_asset/文件名.html
            mWebView.loadUrl("file:///android_asset/javascript.html");
    

    特点
    优点:使用简单
    缺点:存在严重的漏洞问题(Android 4.2之后函数以 @JavascriptInterface进行注解从而避免漏洞攻击)

    • 方式2:通过 WebViewClient 的方法shouldOverrideUrlLoading ()回调拦截 url
      具体原理:
      (1)Android通过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url
      (2)解析该 url 的协议
      (3)如果检测到是预先约定好的协议,就调用相应方法
      具体使用:
      步骤1:在JS约定所需要的Url协议
    <script>
        function callAndroid(){
           /*约定的url协议为:js://webview?arg1=111&arg2=222*/
           document.location = "js://webview?arg1=111&arg2=222";
        }
    </script>
    

    当该JS通过Android的mWebView.loadUrl("file:///android_asset/javascript.html")加载后,就会回调shouldOverrideUrlLoading ().
    步骤2:在Android通过WebViewClient复写shouldOverrideUrlLoading ()

    // 复写WebViewClient类的shouldOverrideUrlLoading方法
    mWebView.setWebViewClient(new WebViewClient() {
         @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")) {
             //  步骤3:
             // 执行JS所需要调用的逻辑
             System.out.println("js调用了Android的方法");
             // 可以在协议上带有参数并传递到Android上
             Set<String> collection = uri.getQueryParameterNames();
             Iterator<String> iterator = collection.iterator();
             while (iterator.hasNext()) {
                 String next = iterator.next();
                 String value = uri.getQueryParameter(next);
                 System.out.println("key:" + next + ",value:" + value);
              }
            }
            return true;
          }
            return super.shouldOverrideUrlLoading(view, url);
       }
     }
    );
    

    特点
    优点:不存在方式1的漏洞;
    缺点:JS获取Android方法的返回值复杂。
    如果JS想要得到Android方法的返回值,只能通过 WebView 的 loadUrl ()去执行 JS 方法把返回值传递回去,相关的代码如下:

    // Android:MainActivity.java
    mWebView.loadUrl("javascript:returnResult(" + result + ")");
    // JS:javascript.html
    function returnResult(result){
        alert("result is" + result);
    }
    
    • 方式3:通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
      在JS中,有三个常用的对话框方法:


      0.4602223544273103.png

      方式3的原理:Android通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调分别拦截JS对话框 (即上述三个方法),得到他们的消息内容,然后解析即可。
      下面的例子将用拦截 JS的输入框(即prompt()方法)说明 :
      a.常用的拦截是:拦截 JS的输入框(即prompt()方法)
      b.因为只有prompt()可以返回任意类型的值,操作最全面方便、更加灵活;而alert()对话框没有返回值;confirm()对话框只能返回两种状态(确定 / 取消)两个值
      步骤1:加载JS代码,如下:

    <script>
        function clickprompt(){
        // 调用prompt()
        var result=prompt("js://demo?arg1=111&arg2=222");
        alert("demo " + result);
        }
    </script>
    

    当使用mWebView.loadUrl("file:///android_asset/javascript.html")加载了上述JS代码后,就会触发回调onJsPrompt(),具体如下:
    如果是拦截警告框(即alert()),则触发回调onJsAlert();
    如果是拦截确认框(即confirm()),则触发回调onJsConfirm();
    步骤2:在Android通过WebChromeClient复写onJsPrompt()

    mWebView.setWebChromeClient(new WebChromeClient() {
    // 拦截输入框(原理同方式2)
    // 参数message:代表promt()的内容(不是url)
    // 参数result:代表输入框的返回值
       @Override
       public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
       // 根据协议的参数,判断是否是所需要的url(原理同方式2)
       // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
       //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的)
            Uri uri = Uri.parse(message);
       // 如果url的协议 = 预先约定的 js 协议
       // 就解析往下解析参数
            if ( uri.getScheme().equals("js")) {
            // 如果 authority  = 预先约定协议里的 webview,即代表都符合约定的协议
            // 所以拦截url,下面JS开始调用Android需要的方法
               if (uri.getAuthority().equals("demo")) {
               // 执行JS所需要调用的逻辑
                   System.out.println("js调用了Android的方法");
                   // 可以在协议上带有参数并传递到Android上
                   HashMap<String, String> params = new HashMap<>();
                   Set<String> collection = uri.getQueryParameterNames();
                   //参数result:代表消息框的返回值(输入值)
                   result.confirm("js调用了Android的方法成功啦");
                }
                return true;
              }
              return super.onJsPrompt(view, url, message, defaultValue, result);
         }
    // 通过alert()和confirm()拦截的原理相同,此处不作过多讲述
    // 拦截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);
         }
     }
    );
    
    0.3452358047020512.png

    4、总结

    0.894173224369111.png

    5、WebView的坑

    (1).API 16之前版本存在远程代码执行漏洞,该漏洞源自于程序没有正确限制使用WebView.addJavascriptInterface方法,攻击者可以使用Java Reflection API利用该漏洞执行任意Java对象和方法。
    (2).WebView的销毁和内存泄漏问题。WebView的完全销毁是件麻烦事,一旦销毁流程不正确,极易容易导致内存泄漏。
    原因:WebView会关联一个Activity,WebView执行的操作是在新线程当中回收,时间Activity没有办法确认,Activity的生命周期和WebView线程生命周期不一致导致WebView一直执行,因为WebView内部持有Activity的引用,导致Activity一直不能被回收,原理类似于匿名内部类持有外部类的引用一样。那么如何解决呢?解决方案如下:
    a.使含WebView的界面在独立进程(销毁时System.exit(0)),简单暴力,涉及到进程间通信。(开发过程中常用)
    b.动态添加WebView,对传入WebView中使用Context弱引用,动态添加WebView意思在布局中创建一个ViewGroup用来放置WebView,Activity创建add进来,Activity停止时remove掉。
    c.从根源解决
    前面的方法都没有解决我内存泄漏的问题,然后我看到了一篇文章是从源码角度分析了webview内存泄漏的原因,最后按作者的方法解决了问题,后面会贴上原文地址。这里简单说一下:
    原文里说的webview引起的内存泄漏主要是因为org.chromium.android_webview.AwContents 类中注册了component callbacks,但是未正常反注册而导致的。
    org.chromium.android_webview.AwContents 类中有这两个方法 onAttachedToWindow 和 onDetachedFromWindow;系统会在attach和detach处进行注册和反注册component callback;
    在onDetachedFromWindow() 方法的第一行中:

    if (isDestroyed()) return;, 
    

    如果 isDestroyed() 返回 true 的话,那么后续的逻辑就不能正常走到,所以就不会执行unregister的操作;我们的activity退出的时候,都会主动调用 WebView.destroy() 方法,这会导致 isDestroyed() 返回 true;destroy()的执行时间又在onDetachedFromWindow之前,所以就会导致不能正常进行unregister()。
    然后解决方法就是:让onDetachedFromWindow先走,在主动调用destroy()之前,把webview从它的parent上面移除掉。
    完整的activity的onDestroy()方法:

    @Override
    protected void onDestroy() {
        if( mWebView!=null) {
            // 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,需要先onDetachedFromWindow(),再
            // destory()
            ViewParent parent = mWebView.getParent();
            if (parent != null) {
                ((ViewGroup) parent).removeView(mWebView);
            }
            mWebView.stopLoading();
            // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
            mWebView.getSettings().setJavaScriptEnabled(false);
            mWebView.clearHistory();
            mWebView.clearView();
            mWebView.removeAllViews();
            mWebView.destroy();
        }
        super.on Destroy();
    }
    

    (3).jsbridge
      通过javascript构建一个桥,桥的两端一个端是客户端,一端是服务端,它可以让本地端调用远端的web代码,也可以让远端调用本地的代码。
    (4).WebViewClient.onPageFinished(不靠谱) –> WebChromeClient.onProgressChanged(靠谱)
    (5).后台耗电(性能优化)
      WebView开启网页时会自己开启线程,如果没有合理的销毁,那么残余线程就会一直运行,so这会非常耗电的,解决方案:有一种暴力方式就是Activity的onDestroy中调用System.exit()方法把虚拟机关闭,也可以结合自己应用的WebView的情况设计出一个温柔的方案。
    (6).WebView硬件加速导致的页面渲染问题
      WebView硬件加速偶尔导致页面白块,页面闪烁,但是加载速度比较快,解决方案:关闭硬件加速。

    例子

    Android studio 中创建html文件
    https://www.jianshu.com/p/9a74d4700e31

    1、先创建一个assets文件夹,在文件夹里创建一个test.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>我是个水哥</title>
    </head>
    <body>
    <input type="text" value="我是输入框" id="edit">
    <button id="btn1" onclick="callAndroid()">调用Android方式1</button>
    <button id="btn2" onclick="callAndroid2()">调用Android方式2</button>
    <button id="btn3" onclick="callAndroid3()">调用Android方式3</button>
    
    
    <script>
      //Android调用Js
      function callJs(msg) {
        //想要传递过来的内容显示在输入框中
        var edit = document.getElementById("edit");
        edit.value = msg;
    
      }
    
      //Js调用Android--方法1,addJavaScriptInterface
      function callAndroid() {
        //android要通过对象调用方法,所以需要将java的对象映射过来
        // 由于对象映射,所以调用test对象等于调用Android映射的对象
        window.zhangsan.callAndroid("js调用了android中的方法");
      }
    
      //Js调用Android--方法2,shouldOverrideUrlLoading
     function callAndroid2(){
        /*约定的url协议为:js://webview?arg1=111&arg2=222*/
        document.location = "js://webview?arg1=111&arg2=222";
     }
    
      //Js调用Android--方法3,WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()
     function callAndroid3(){
        // 调用prompt()
        var result=prompt("js://demo?arg1=3333&arg2=4444");
         //弹窗
        alert(result);
     }
    
    </script>
    </body>
    </html>
    
    2、xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/btn1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Android调用JS-----1"/>
        <Button
            android:id="@+id/btn2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Android调用JS-----2"/>
    
        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        </WebView>
    
    </LinearLayout>
    
    3、AndroidJs(一个与JS对象映射关系的Android类)(JS通过WebView调用 Android 代码时方式1时使用)
    import android.webkit.JavascriptInterface;
    
    // 继承自Object类
    public class AndroidJs extends Object {
        // 定义JS需要调用的方法
        // 被JS调用的方法必须加入@JavascriptInterface注解
        @JavascriptInterface
        public void hello(String msg) {
            System.out.println("JS调用了Android的hello方法");
        }
    }
    
    4、Activity
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.webkit.JsPromptResult;
    import android.webkit.JsResult;
    import android.webkit.ValueCallback;
    import android.webkit.WebChromeClient;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Button;
    import android.widget.Toast;
    
    import java.util.Iterator;
    import java.util.Set;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Button btn1;
        private Button btn2;
        private WebView webview;
        private String msg = "哈哈哈哈哈哈哈哈哈";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            btn1 = (Button) findViewById(R.id.btn1);
            btn2 = (Button) findViewById(R.id.btn2);
            webview = (WebView) findViewById(R.id.webview);
    
            // 设置与Js交互的权限
            WebSettings settings = webview.getSettings();
    
            // 设置允许JS弹窗
            settings.setJavaScriptEnabled(true);
    
            // 先载入JS代码
            // 格式规定为:file:///android_asset/文件名.html
            webview.loadUrl("file:///android_asset/test.html");
    
            //Js调用Android方法1
            //参数1,桥梁类的对象
            //参数2,对象的名字
            //AndroidJs zhangsan = new AndroidJs();
            webview.addJavascriptInterface(new AndroidJs(), "zhangsan");
    
            //Js调用Android--方法2,shouldOverrideUrlLoading
            // 复写WebViewClient类的shouldOverrideUrlLoading方法
            webview.setWebViewClient(new WebViewClient() {
                                         @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")) {
                                                     //  步骤3:
                                                     // 执行JS所需要调用的逻辑
                                                     System.out.println("js调用了Android的方法");
                                                     // 可以在协议上带有参数并传递到Android上
                                                     Set<String> collection = uri.getQueryParameterNames();
                                                     Iterator<String> iterator = collection.iterator();
                                                     while (iterator.hasNext()) {
                                                         String next = iterator.next();
                                                         String value = uri.getQueryParameter(next);
                                                         System.out.println("key:" + next + ",value:" + value);
                                                     }
                                                 }
                                                 return true;
                                             }
                                             return super.shouldOverrideUrlLoading(view, url);
                                         }
                                     }
            );
    
            //Js调用Android--方法3,WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()
            webview.setWebChromeClient(
                    new WebChromeClient() {
                        // 拦截输入框(原理同方式2)
                        // 参数message:代表promt()的内容(不是url)
                        // 参数result:代表输入框的返回值
                        @Override
                        public boolean onJsPrompt(WebView view, String url, String message,
                                                  String defaultValue, JsPromptResult result) {
                            // 根据协议的参数,判断是否是所需要的url(原理同方式2)
                            // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
                            //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的)
                            Uri uri = Uri.parse(message);
                            // 如果url的协议 = 预先约定的 js 协议
                            // 就解析往下解析参数
                            if (uri.getScheme().equals("js")) {
                                // 如果 authority  = 预先约定协议里的 webview,即代表都符合约定的协议
                                // 所以拦截url,下面JS开始调用Android需要的方法
                                if (uri.getAuthority().equals("demo")) {
                                    // 执行JS所需要调用的逻辑
                                    System.out.println("js调用了Android的方法");
                                    // 可以在协议上带有参数并传递到Android上
                                    Set<String> collection = uri.getQueryParameterNames();
                                    Iterator<String> iterator = collection.iterator();
                                    while (iterator.hasNext()) {
                                        String next = iterator.next();
                                        String value = uri.getQueryParameter(next);
                                        System.out.println("key:" + next + ",value:" + value);
                                    }
                                    //参数result:代表消息框的返回值(输入值)
                                    result.confirm("第三种方法的Android的返回值");
                                }
                                return true;
                            }
                            return super.onJsPrompt(view, url, message, defaultValue, result);
                        }
    
                        // 通过alert()和confirm()拦截的原理相同,此处不作过多讲述
                        // 拦截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);
                        }
                    }
            );
    
            btn1.setOnClickListener(this);
            btn2.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn1:
                    webview.loadUrl("javascript:callJs('" + msg + "')");
                    break;
                case R.id.btn2:
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        webview.evaluateJavascript("javascript:callJs('" + msg + "')", new ValueCallback<String>() {
                            @Override
                            public void onReceiveValue(String value) {
                                //接收返回值用的
                                Toast.makeText(MainActivity.this, value, Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                    break;
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:WebView与JS交互

          本文链接:https://www.haomeiwen.com/subject/jmbdaqtx.html