【Android WebView】Android和JS互调,BridgeWebView的使用

本文详细介绍Android与JavaScript间的交互方法,包括Android调用JS的两种方式:loadUrl与evaluateJavascript,以及JS调用Android的方法。此外还介绍了BridgeWebView组件的使用。

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

前言

上篇介绍了WebView的基本使用,WebView使用中常用的类和方法。本篇将介绍WebViewAndroid原生Javascript之间交互。以及它们之间通信桥梁JSBridge


1、Android调用JS

Android调用Javascript有两种方法,第一种是通过loadUrl方法,第二种是通过evaluateJavascript

1-1.loadUrl示例

首先新建index.html放在android工程的assets目录下。

看下Html中的Javascript代码和Android中调用,JS代码相对比较简单。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>WebView测试</title>
	</head>

	<script type="text/javascript">
		<!--android将调用的方法-->
        function androidCallJs(){
            alert("android 调用了 JS了")
        }
	</script>
</html>

看下Android中如何实现调用JavaScript代码的。

布局文件:

<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<Button
    android:id="@+id/callJsBtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="点击调用 JS" />
    

Kotlin代码:


 //初始化webview
 val webView = getView(R.id.webview)
      
 //设置webview选项参数
 val webSetting = webView!!.settings

 //设置webview可以调用javascript代码
 webSetting.javaScriptEnabled = true

 //设置javascript可以自动弹弹窗
 webSetting.javaScriptCanOpenWindowsAutomatically = true

 //加载html,这里android_asset是固定写法
 webView!!.loadUrl("file:///android_asset/index.html")

 callJsBtn = getView(R.id.callJsBtn)

 callJsBtn!!.setOnClickListener {
  //点击调用Js方法
   webView!!.loadUrl("javascript:androidCallJs()")
  }

  //webview是加载整个html作用,内容的渲染需要使用它的功能辅助类WebviewChromClient类去实现
  webView!!.webChromeClient = object : WebChromeClient() {

    override fun onJsAlert(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
    
       val b = AlertDialog.Builder(this@MainActivity);
       b.setTitle("Android Call Js")
       b.setMessage(message)
       b.setPositiveButton("确定",object :DialogInterface.OnClickListener{
                  override fun onClick(dialog: DialogInterface?, which: Int) {
                result!!.confirm()
            }
        })
        b.setCancelable(false)
        b.create().show()
        return true
    }

}

Android调用JS

1-2、evaluateJavascript示例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>WebView测试</title>
	</head>
	
	<script type="text/javascript">
	  //android调用js代码第二种方法 
      function androidCallJs(){
           alert("android evaluateJs 调用了 JS了")
           
           return "Android你能收到消息吗?"
       }
	</script>
</html>

callJsBtn!!.setOnClickListener {
    //第二种方法调用JS
	webView!!.evaluateJavascript("javascript:androidCallJs()", object : ValueCallback<String> {
       //Js返回的值
       override fun onReceiveValue(value: String?) {     
              ToastUtils.show(value!!)
       }
     })
      // webView!!.loadUrl("javascript:androidCallJs()")
}

这里写图片描述

只要将第一种方法loadUrl更换为evaluateJavascript方法即可。这种方法相比较第一种方法,能够接收到Javascript返回值,loadUrl只能显示。

2、JS调用Android

2-1.WebView提供方法 addJavascriptInterfaceJavascriptAndroid建立映射关系。

2-1-1.Html声明映射对象以及Android被调用的方法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>JS调用Android测试1</title>
	</head>

	<script type="text/javascript">

      function JsCallAndroid(){
		<!--testHello是android中注册的对象,helloJs()是android中的方法-->
		testHello.helloJs("JsCallAndroid")

	  }
	</script>

	<body>
		<button type="button" id="btn" onclick="JsCallAndroid()">点击调用Android代码</button>
	</body>
</html>

2-1-2、定义与Javascript映射关系的Android类

class AndroidToJs : Object() {
	//注解映射
    @JavascriptInterface
    fun helloJs(msg: String) {
        ToastUtils.show("Js 调用了 Android helloJs方法了")
    }
}

2-1-3、Kotlin添加Javascript和Android映射关系

//初始化webview
webView = getView(R.id.webview)

//设置webview选项参数
val webSetting = webView!!.settings

//设置webview可以调用javascript代码
webSetting.javaScriptEnabled = true

//加载html
webView!!.loadUrl("file:///android_asset/index.html")

//Webview添加Js和Android映射关系
webView!!.addJavascriptInterface(AndroidToJs(), "testHello")

AndroidToJsAndroid的映射类。Kotiln的写法。testHello是映射到Javascript的映射类的对象,名字可以随意取。

Js调用Android

2-2、WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截消息解析。

<!DOCTYPE html>
<html>
     <head>
	     <meta charset="utf-8">
	     <title>JS调用Android测试1</title>
      </head>
	  <script>
		 function clickprompt(){
         // 调用prompt()  定义js和android通信协议
	     var result=prompt("js://test?param1=hello11&param1=hello22");
	     alert("test" + result);
        }
      </script>

      <!-- 点击按钮则调用clickprompt()  -->
      <body>
         <button type="button" id="btn" onclick="clickprompt()">点击调用Android代码</button>
        </body>
    </html>

webView!!.webChromeClient = object : WebChromeClient() {

    override fun onJsPrompt(view: WebView?, url: String?, message: String?, defaultValue: String?, result: JsPromptResult?): Boolean {
         val uri = Uri.parse(message)
         // 如果uri协议 = 预先约定的 js 协议,解析参数
         if (uri.scheme == "js") {
             // 如果 authority  = 预先约定协议里的 webview,即代表都符合约定的协议
             // 所以拦截url,下面JS开始调用Android需要的方法
             if (uri.authority == "webview") {
             // 执行JS所需要调用的逻辑
             ToastUtils.show("Js 调用了 Android 中 helloToJS代码")

             // 可以在协议上带有参数并传递到Android上
             val params = HashMap<String, String>()
             var collection = uri!!.queryParameterNames

             //参数result:代表消息框的返回值(输入值)
             result!!.confirm("js调用了Android的方法成功啦")

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

WebViewAndroid4.2以下版本产生安全问题有一种情况就是通过第一种添加JavascriptAndroid映射关系的方式。第二种方式就是较为安全,不会产生安全漏洞问题。但是要Androidjs约定一个协议通信,相对实现起来比较复杂,onJsAlertonJsConfirm和上述实现方式一样。

3、BridgeWebView

BridgeWebView,继承了WebView类,实现了WebViewJavascriptBridge接口,这里介绍下它的使用方式。

3-1.Gradle引入

compile 'com.github.lzyzsd:jsbridge:1.0.4'

3-2、使用方法

3-2-1、自定义JS事件回调类

private class MyHadlerCallBack extends DefaultHandler {

   @Override
   public void handler(String data, CallBackFunction function) {
	   if (function != null) {
	       Toast.makeText(JsBridgeVoteActivity.this, "自定义类继承DefaultHandler:" + data, Toast.LENGTH_SHORT).show();
         }
     }
}

3-2-2、自定义JS事件回调类


BridgeWebView webView = new BridgeWebView(this);
//设置默认回调处理类
webView.setDefaultHandler(new MyHadlerCallBack());
//注册Js和android之间通信的事件
webView.registerHandler("openLogin", (data, function) -> openLogin());

以上面的代码为例,在Android中注册了事件openLogin,这里也需要在Html页面的Javascript代码中进行注册相同的事件名称 openLogin。意味着在Html页面上用户(未登录情况下)触发登录操作。登录事件要在isBindPhone代码中完成。


private void openLogin() {
   new LoginDialog(this, new LoginDialog.OnLoginCallBack() {
        @Override
        public void login() {
		 HashMap<String, Object> params = new HashMap<>();
		 /*method是和js约定,这是调用方法,后面是登录成功操作*/
            params.put("method", "loginSuccess");
            /*webView通知js已经登录成功*/
            webView.callHandler("call", new Gson().toJson(params), data ->{                

            });
         }
  }).show();
}

Javascript调用Android登录方法,Android端登录成功后通过webView.callHandler方法通知h5页面客户端登录成功,做相应的操作即可。BridgeWebView的使用方法就是这么简单,内部已经将通信机制封装好。


总结

本篇介绍了WebView上js和Android互相调用方法。在大前端概念的趋势下,原生AndroidH5的联系会越来越紧密。下篇将介绍在重构过程中WebView上遇到的问题,以及WebView最让人关系的内存泄漏问题以及解决方案。对于H5Java层结合的混合开发Hybrid的研究也将在以后的WebView系列中做介绍。

Android WebView系列(一)WebView的基本使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值