• 【Android 】WebView和原生控件交互


    一、原生调用 Webview

    使用前准备

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title> Android调用 JavaScript</title>
    </head>
    <body>
        <h1>这是H1</h1>
        <script>
            // Android需要调用的方法
            function callJS() {
                alert("Android调用了JS的callJS方法");
            }
        </script>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1.1 方法1:loadUrl方法

    webView.loadUrl("javascript:callJS()");
    
    • 1

    1.2 方式2:evaluateJavascript方法

     webView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
                 @Override
                 public void onReceiveValue(String value) {
                     //此处为 js 返回的结果
                  
                 }
             });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二、Webview调用 原生控件

    2.1 方式1:addJavascriptInterface方法

    步骤一:定义实体类

    public class AndroidtoJs  {
    
        // 定义JS需要调用的方法
        // 被JS调用的方法必须加入@JavascriptInterface注解
        @JavascriptInterface
        public void hello(String msg) {
              Log.i("AndroidtoJs","msg:"+msg);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    步骤2:添加html代码

    DOCTYPE html>
    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>WebView Studytitle>
        <script>
            function callAndroid() {
                test.hello("js调用了android中的hello方法");
            }
        script>
    head>
    
    <body>
        <button type="button" id="button1" onclick="callAndroid()">callAndroidbutton>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    步骤3:java调用代码

    //AndroidtoJS类对象映射到js的test对象
    webView.addJavascriptInterface(new AndroidtoJs(), "test");
    
    • 1
    • 2

    2.2 方式2:shouldOverrideUrlLoading 方法

    步骤1:添加html代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>lucashu</title>
        <script>
             function callAndroid(){
                 document.location = "js://webview?arg1=111&arg2=222";
             }
          </script>
    </head>
    <body>
    
    <button type="button" id="button1" onclick="callAndroid()">callAndroid</button>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    步骤2:
    重写WebViewClientshouldOverrideUrlLoading 方法

    @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          Log.d("MainActivity", "shouldOverrideUrlLoading:"+url);
          return true;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.3 方式3:onJsAlertonJsConfirmonJsPrompt方法

    步骤1:添加html代码

    DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>lucashutitle>
        <script>
             function callAndroid(){
                 prompt("js://webview?arg1=111&arg2=222");
             }
          script>
    head>
    <body>
    
    <button type="button" id="button1" onclick="callAndroid()">callAndroidbutton>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    重写WebChromeClientonJsPrompt 方法

          @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        Log.d("MainActivity","onJsPrompt:"+ message);
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    三、第三方框架 jsbridge

    官网:https://github.com/lzyzsd/JsBridge

    3.1 使用方法

    repositories {
        // ...
        maven { url "https://jitpack.io" }
    }
    
    dependencies {
        compile 'com.github.lzyzsd:jsbridge:1.0.4'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.2 js调用native 带回调通用方法

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>lucashu</title>
        <script>
         //h5直接通过send向Native发送消息,在MyHandlerCallBack的Handler里接收,并可通过onCallBack方法回传
            function sendClick() {
                var name = document.getElementById("uname").value;
                var pwd = document.getElementById("psw").value;
                var data = "name = " + name + ", password = " + pwd;
    
                window.WebViewJavascriptBridge.send(
                    data,
                    function(responseData) {
                        document.getElementById("show").innerHTML = responseData
                    }
                );
            }
            function connectWebViewJavascriptBridge(callback) {
                if (window.WebViewJavascriptBridge) {
                    callback(WebViewJavascriptBridge)
                } else {
                    document.addEventListener(
                        'WebViewJavascriptBridgeReady',
                        function () {
                            callback(WebViewJavascriptBridge)
                        },
                        false
                    );
                }
            }
    
            // 第一连接时初始化bridage
            connectWebViewJavascriptBridge(function (bridge) {
                //也注册默认的Handler,用来接收java调用的send(string,CallBackFunction)方法
                bridge.init(function (message, responseCallback) {
                    console.log('JS got a message', message);
                    var data = {
                        'Javascript Responds': '测试中文!'
                    };
                    console.log('JS responding with', data);
                    responseCallback(data);
                });
                //注册handler等待java代码调用
                //初始化时获取数据是调用此处代码
                //参数:标识,要传递到JAVA的数据,回调方法。
                //JAVA代码响应的方法:mBridgeWebview.callHandler("functionInJs", new Gson().toJson(实体类对象), new CallBackFunction(){onCallBack(String data)}
                bridge.registerHandler("functionInJs", function (data, responseCallback) {
                    document.getElementById("show").innerHTML = ("data from Java: = " + data);
                    var responseData = "I am javascript, Data reception success!";
                    responseCallback(responseData);
                });
            })
        </script>
    </head>
    
    <body>
    <p>
        <input type="text" id="uname" value="用户名" />
    </p>
    <p>
        <input type="text" id="psw" value="密码" />
    </p>
    <button type="button" id="button1" onclick="sendClick()">发给Native</button>
    <p>
    <div id="show">Native将要回传回来的数据展示</div>
    </p>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    java端代码

     webView.loadUrl("file:///android_asset/test.html");
            WebSettings webSettings = webView.getSettings();
            webView.clearCache(true);
            webSettings.setJavaScriptEnabled(true);
    
            webView.setDefaultHandler(new BridgeHandler() {
                @Override
                public void handler(String data, CallBackFunction function) {
                    Log.i(TAG, "handler  web data = " + data);
                    function.onCallBack("从java端传回的数据");
                }
            });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.3 js调用native 带回调发送给特定方法

    html代码

    DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>lucashutitle>
        <script>
            function clickAlert() {
                var name = document.getElementById("uname").value;
                var pwd = document.getElementById("psw").value;
                var data = "name = " + name + ", password = " + pwd;
                WebViewJavascriptBridge.callHandler(
                    'submitFromWeb', {
                        'param': data
                    },
                    function (responseData) {
                        document.getElementById("show").innerHTML = responseData;
                    }
                );
            }
    
            function connectWebViewJavascriptBridge(callback) {
                if (window.WebViewJavascriptBridge) {
                    callback(WebViewJavascriptBridge)
                } else {
                    document.addEventListener(
                        'WebViewJavascriptBridgeReady',
                        function () {
                            callback(WebViewJavascriptBridge)
                        },
                        false
                    );
                }
            }
    
            // 第一连接时初始化bridage
            connectWebViewJavascriptBridge(function (bridge) {
                //也注册默认的Handler,用来接收java调用的send(string,CallBackFunction)方法
                bridge.init(function (message, responseCallback) {
                    console.log('JS got a message', message);
                    var data = {
                        'Javascript Responds': '测试中文!'
                    };
                    console.log('JS responding with', data);
                    responseCallback(data);
                });
                //注册handler等待java代码调用
                //初始化时获取数据是调用此处代码
                //参数:标识,要传递到JAVA的数据,回调方法。
                //JAVA代码响应的方法:mBridgeWebview.callHandler("functionInJs", new Gson().toJson(实体类对象), new CallBackFunction(){onCallBack(String data)}
                bridge.registerHandler("functionInJs", function (data, responseCallback) {
                    document.getElementById("show").innerHTML = ("data from Java: = " + data);
                    var responseData = "I am javascript, Data reception success!";
                    responseCallback(responseData);
                });
            })
        script>
    head>
    
    <body>
    <p>
        <input type="text" id="uname" value="用户名" />
    p>
    
    <p>
        <input type="text" id="psw" value="密码" />
    p>
    <button type="button" id="button1" onclick="clickAlert()">获取用户名和密码button>
    
    <p>
    <div id="show">Native将要回传回来的数据展示div>
    p>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    java代码

     webView.loadUrl("file:///android_asset/test.html");
     WebSettings webSettings = webView.getSettings();
     webView.clearCache(true);
     webSettings.setJavaScriptEnabled(true);
     webView.registerHandler("submitFromWeb", new BridgeHandler() {
         @Override
         public void handler(String data, CallBackFunction function) {
             Log.i(TAG, "handler  web data = " + data);
             function.onCallBack("从java端传回的数据");
         }
     });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.4 native 发送数据给js

    DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>lucashutitle>
        <script>
            //Native方法直接调用,示例代码:mBridgeWebview.loadUrl("javascript:nativeFunction('" + data + "')");
            function nativeFunction(data) {
                document.getElementById("show").innerHTML = data;
            }
            function connectWebViewJavascriptBridge(callback) {
                if (window.WebViewJavascriptBridge) {
                    callback(WebViewJavascriptBridge)
                } else {
                    document.addEventListener(
                        'WebViewJavascriptBridgeReady',
                        function () {
                            callback(WebViewJavascriptBridge)
                        },
                        false
                    );
                }
            }
    
            // 第一连接时初始化bridage
            connectWebViewJavascriptBridge(function (bridge) {
                //也注册默认的Handler,用来接收java调用的send(string,CallBackFunction)方法
                bridge.init(function (message, responseCallback) {
                    console.log('JS got a message', message);
                    var data = {
                        'Javascript Responds': '测试中文!'
                    };
                    console.log('JS responding with', data);
                    responseCallback(data);
                });
                //注册handler等待java代码调用
                //初始化时获取数据是调用此处代码
                //参数:标识,要传递到JAVA的数据,回调方法。
                //JAVA代码响应的方法:mBridgeWebview.callHandler("functionInJs", new Gson().toJson(实体类对象), new CallBackFunction(){onCallBack(String data)}
                bridge.registerHandler("functionInJs", function (data, responseCallback) {
                    document.getElementById("show").innerHTML = ("data from Java: = " + data);
                    var responseData = "I am javascript, Data reception success!";
                    responseCallback(responseData);
                });
            })
        script>
    head>
    
    <body>
     
    <div id="show">Native将要回传回来的数据展示div>
    p>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    java端

       webView.loadUrl("file:///android_asset/test.html");
            WebSettings webSettings = webView.getSettings();
            webView.clearCache(true);
            webSettings.setJavaScriptEnabled(true);
            Button button = findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    webView.loadUrl("javascript:nativeFunction('data')");
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.5其他方法

    DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>lucashutitle>
        <script>
            //Native方法直接调用,示例代码:mBridgeWebview.loadUrl("javascript:nativeFunction('" + data + "')");
            function nativeFunction(data) {
                document.getElementById("show").innerHTML = data;
            }
            function connectWebViewJavascriptBridge(callback) {
                if (window.WebViewJavascriptBridge) {
                    callback(WebViewJavascriptBridge)
                } else {
                    document.addEventListener(
                        'WebViewJavascriptBridgeReady',
                        function () {
                            callback(WebViewJavascriptBridge)
                        },
                        false
                    );
                }
            }
    
            // 第一连接时初始化bridage
            connectWebViewJavascriptBridge(function (bridge) {
                //也注册默认的Handler,用来接收java调用的send(string,CallBackFunction)方法
                bridge.init(function (message, responseCallback) {
                    console.log('JS got a message', message);
                    var data = {
                        'Javascript Responds': '测试中文!'
                    };
                    console.log('JS responding with', data);
                    responseCallback(data);
                });
                //注册handler等待java代码调用
                //初始化时获取数据是调用此处代码
                //参数:标识,要传递到JAVA的数据,回调方法。
                //JAVA代码响应的方法:mBridgeWebview.callHandler("functionInJs", new Gson().toJson(实体类对象), new CallBackFunction(){onCallBack(String data)}
                bridge.registerHandler("functionInJs", function (data, responseCallback) {
                    document.getElementById("show").innerHTML = ("data from Java: = " + data);
                    var responseData = "I am javascript, Data reception success!";
                    responseCallback(responseData);
                });
            })
        script>
    head>
    
    <body>
    <p>
        <input type="text" id="uname" value="用户名" />
    p>
    <p>
        <input type="text" id="psw" value="密码" />
    p>
    <button type="button" id="button1" onclick="sendClick()">发给Nativebutton>
    <p>
    <div id="show">Native将要回传回来的数据展示div>
    p>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    java

    webView.loadUrl("file:///android_asset/test.html");
            WebSettings webSettings = webView.getSettings();
            webView.clearCache(true);
            webSettings.setJavaScriptEnabled(true);
            Button button = findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //应用启动后初始化数据调用,js处理方法connectWebViewJavascriptBridge(function(bridge)
                    webView.callHandler("functionInJs", "username passwod", new CallBackFunction() {
                        @Override
                        public void onCallBack(String data) {
                            Toast.makeText(MainActivity.this, "向h5发送初始化数据成功,接收h5返回值为:" + data, Toast.LENGTH_SHORT).show();;
                        }
                    });
                }
            });
    
            //对应js中的bridge.init处理,此处需加CallBackFunction,如果只使用mBridgeWebview.send("");会导致js中只收到通知,接收不到值
            webView.send("来自java的发送消息!!!", new CallBackFunction() {
                @Override
                public void onCallBack(String data) {
                    Toast.makeText(MainActivity.this, "bridge.init初始化数据成功" + data, Toast.LENGTH_SHORT).show();
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    Java基础面试高频问题总结(二)
    利用Paddle OCR进行文字识别
    Visual Studio上一些Error的解决方案
    矩阵微积分
    Midjourney是个什么软件?midjourney订阅教程
    LeetCode----72. 编辑距离
    外贸独立站的运营效果到底如何
    【C++】二叉树进阶 -- 详解
    SQL注入案例
    汽车数字化转型:存储驱动创新未来
  • 原文地址:https://blog.csdn.net/huweiliyi/article/details/105895759