Android开发之Webview中原生与JS交互

待我称王封你为后i 2022-05-07 02:28 607阅读 0赞

文章目录

  • 概述
  • 使用场景
  • 交互方式
    • Java调用JS代码
    • JS调用Java代码
  • 总结

概述

由于手机硬件资源的快速提升,使得采用混合开发的可能性逐渐成为现实并且流行起来。Android开发中最为简单的方式就是通过Webview来嵌入一个网页使web作为App的一部分。

使用场景

  1. 非重交互场景
  2. 非计算密集型场景
  3. 对UI复杂度要求不高的场景
    以上可见,《王者荣耀》断然不会使用混合开发的,其实谷歌举了两个最适合的场景:
    第一:内容需要动态更新的场景,例如APP里面的法律条款展示等。
    第二:总是需要通过网络来拉取展示内容的场景,例如新闻展示。

交互方式

我们知道,网页的行为现在是使用JavaScript来处理的,而Android原生使用的是Java(Kotlin),交互的意思即原生可以调用JavaScript方法,而JavaScript也可以调用原生的方法。

Java调用JS代码的方法有2种:

  1. 通过WebView的loadUrl() 方法
  2. 通过WebView的evaluateJavascript()方法

JS调用Java代码的方法有3种:

  1. 通过WebView的addJavascriptInterface()进行对象映射
  2. 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
  3. 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

先上一张效果图:
在这里插入图片描述

Java调用JS代码

上面提到Android提供了两种方法来实现Java执行Js代码,其中evaluateJavascript()方法是从 API 19(4.4版本)开始提供的,而现在Android已经发布到 API 28 (9.0)了, 4.4以下版本占的比例已经非常少了,相信过不了多久基本上就不存在了,所以我们要放下历史包袱,直接使用新的方法。最重要的是,在Android 4.4及其以上版本Google 采用了 Chromium(http://www.chromium.org/) 作为系统WebView的底层内核,而不是WebKit了。新的webview对HTML5,CSS3,Javascript的支持更为广泛,而且js执行引擎直接换成了V8,执行效率大大提升.

  1. void evaluateJavascript(String script, ValueCallback<String> resultCallback){}

参数script : 要执行的JS代码。
参数 resultCallback: Js代码执行后的返回值

具体步骤:
第一:新建一个工程,新建一个Activity,包含一个Webview控件。
第二:新建一个demo.html的文档,作为要在webview中展示的web页面,里面含有js代码。将其放在工程中的assets文件家中。

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="zh-cmn-Hans">
  4. <meta charset="UTF-8">
  5. <meta name="renderer" content="webkit">
  6. <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  7. <meta name="viewport" content="width=device-width"/>
  8. <title>JsBridgeDemo</title>
  9. </head>
  10. <style>
  11. .btn {
  12. text-align: center;
  13. background: #d8d8d8;
  14. color: #222;
  15. padding: 20px;
  16. margin: 30px;
  17. font-size: 24px;
  18. border-radius: 4px;
  19. box-shadow: 4px 2px 10px #999;
  20. }
  21. .btn:active {
  22. opacity: .7;
  23. box-shadow: 4px 2px 10px #555;
  24. }
  25. </style>
  26. <body>
  27. <div class="btn" onclick="showAndroidToast('Js调用Java')">Js调用Java函数</div>
  28. <p id="content"></p>
  29. <script type="text/javascript">
  30. function showAndroidToast(toast) {
  31. android.showToast(toast);
  32. }
  33. function fillContent(){
  34. document.getElementById("content").innerHTML ="此处内容由Java调用Js方法展示在Webview上";
  35. return "ok";
  36. }
  37. </script>
  38. </body>

第三步:在activity中通过webview调用Js代码。

  1. final WebView myWebView=findViewById(R.id.webView);
  2. WebSettings webSettings=myWebView.getSettings();
  3. webSettings.setJavaScriptEnabled(true);
  4. myWebView.loadUrl("file:///android_asset/demo.html");
  5. Button btnCallJs=findViewById(R.id.btn_call_js);
  6. btnCallJs.setOnClickListener(new View.OnClickListener() {
  7. @Override
  8. public void onClick(View v) {
  9. myWebView.evaluateJavascript("fillContent()", new ValueCallback<String>() {
  10. @Override
  11. public void onReceiveValue(String value) {
  12. Toast.makeText(MainActivity.this,value,Toast.LENGTH_SHORT).show();
  13. }
  14. });
  15. }
  16. });

首先设置允许Webview执行Js,然后加载assets文件夹中的demo.html网页,最后在点击按钮的时候使用evaluateJavascript()方法来执行Js代码。

JS代码的调用需要在web页面加载完成后才可以正常执行。可以通过监听WebViewClient的onPageFinished 回调来完成,如下代码所示。

  1. myWebView.setWebViewClient(new WebViewClient(){
  2. @Override
  3. public void onPageFinished(WebView view, String url){
  4. super.onPageFinished(view, url);
  5. //执行Js代码
  6. }
  7. });

JS调用Java代码

上面提到有三种方法可以实现Js调用Java代码的目的,其中第一种简单明了,为Google推荐的方法,但是其在API 17(4.2)之前存在任意执行漏洞。但是我们前面分析了,4.4 都快没有了,4.2 就更别说了,所以我们直接针对Android4.4编程,使用这个方法是安全的。

具体步骤:
第一步:新建一个接口类JavaInterface ,里面定义给Js调用的方法。这些方法必须是public的,而且必须使用@JavascriptInterface进行注解,例如下面的代码示例中的showTost()

  1. public class JavaInterface {
  2. private Context mContext;
  3. JavaInterface(Context c) {
  4. mContext = c;
  5. }
  6. @JavascriptInterface
  7. public void showToast(String toast) {
  8. Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
  9. }
  10. }

第二步:给Webview添加与Js的映射关系

  1. myWebView.addJavascriptInterface(new JavaInterface(this),"android");

参数1:接口类的对象
参数2:Java对象映射到Js的对象名,可以在Js中使用这个对象来调用接口类中的方法。

第三步:在Js中调用Java方法

  1. <script type="text/javascript">
  2. function showAndroidToast(toast) {
  3. android.showToast(toast);
  4. }
  5. </script>

可以看到,在js中可以使用android这个Js对象,直接调用我们定义在JavaInterface类中的方法。

总结

以上就是Android开发中使用Webview 完成原生与web的交互。开篇说道除了本文介绍的方式,还有其他几种方式,大部分不是有历史包袱就是本意不是用来做这件事情的,所以应该优先使用本文的方式,如果有的同学需要了解其他方法,可以参考这篇博客,写的比较全。

如果是在项目中使用而不是为了学习,推荐使用前人写好的三方库,例如DSBridge,JsBridge等。特别是dsbridge,三端全有,现代简洁,易用。

发表评论

表情:
评论列表 (有 0 条评论,607人围观)

还没有评论,来说两句吧...

相关阅读

    相关 WebViewJS交互

    阅读:[JSBridge][] 前言:以下是webView和JS互相调用的基础介绍。 利用WebView调用网页上的JavaScript代码(java调用JS) 说白