【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.1 方法1:loadUrl方法

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

1.2 方式2:evaluateJavascript方法

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

二、Webview调用 原生控件

2.1 方式1:addJavascriptInterface方法

步骤一:定义实体类

public class AndroidtoJs  {
    
    

    // 定义JS需要调用的方法
    // 被JS调用的方法必须加入@JavascriptInterface注解
    @JavascriptInterface
    public void hello(String msg) {
    
    
          Log.i("AndroidtoJs","msg:"+msg);
    }
}

步骤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 Study</title>
    <script>
        function callAndroid() {
      
      
            test.hello("js调用了android中的hello方法");
        }
    </script>
</head>

<body>
    <button type="button" id="button1" onclick="callAndroid()">callAndroid</button>
</body>

</html>

步骤3:java调用代码

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

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>

步骤2:
重写WebViewClientshouldOverrideUrlLoading 方法

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

2.3 方式3:onJsAlertonJsConfirmonJsPrompt方法

步骤1:添加html代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>lucashu</title>
    <script>
         function callAndroid(){
      
      
             prompt("js://webview?arg1=111&arg2=222");
         }
      </script>
</head>
<body>

<button type="button" id="button1" onclick="callAndroid()">callAndroid</button>
</body>
</html>

重写WebChromeClientonJsPrompt 方法

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

在这里插入图片描述

三、第三方框架 jsbridge

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

3.1 使用方法

repositories {
    
    
    // ...
    maven {
    
     url "https://jitpack.io" }
}

dependencies {
    
    
    compile 'com.github.lzyzsd:jsbridge:1.0.4'
}

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>

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端传回的数据");
            }
        });

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

html代码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>lucashu</title>
    <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>

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端传回的数据");
     }
 });

3.4 native 发送数据给js

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>lucashu</title>
    <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>

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')");
            }
        });

3.5其他方法

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>lucashu</title>
    <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()">发给Native</button>
<p>
<div id="show">Native将要回传回来的数据展示</div>
</p>
</body>

</html>

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();
            }
        });

猜你喜欢

转载自blog.csdn.net/huweiliyi/article/details/105895759