Android webview与js的数据交互

作者:米心语 时间:2021-08-18 02:56:32 

项目要用到Webview和js交互,查了查以前的项目感觉还是有必要整理下的。

简单描述下项目中用到的地方,比如说在web页需要用到登录的地方点击登录跳转到APP原生登录界面去登录,点击web页的拨打电话弹出原生dialog询问是否拨打,点击web页里面的图片进行放大处理。针对于上述的需求我们通用的方式大概有两种,一是监听a标签,在shouldOverrideUrlLoading根据URL进行判断,二是js代码注入,找到我们想要处理的元素进行js代码注入。下面就这两种方式简单的进行描述

首先需要初始化WebView以及设置支持JavaScript,常用的配置属性有一下几种,可以在项目中根据需求添加


WebSettings webSetting = webView.getSettings();
// 支持JavaScript
webSetting.setJavaScriptEnabled(true);
// 设置可以访问文件s
webSetting.setAllowFileAccess(true);
// 告诉javascript来自动打开的窗口。这适用于JavaScript函数的窗口,open()。
webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
// 支持缩放
webSetting.setSupportZoom(true);
// 是否禁止是网络加载数据
webSetting.setBlockNetworkLoads(false);
// 设置是否支持多窗口
webSetting.setSupportMultipleWindows(true);
// 是否开启本地DOM存储
webSetting.setDomStorageEnabled(true);
// 设置不缓存
webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
// 阻塞加载图片
webSetting.setBlockNetworkImage(false);
// 支持启用插件
webSetting.setPluginState(WebSettings.PluginState.ON);
// 设置任意比较缩放为真
webSetting.setUseWideViewPort(true);
// 设置WebView加载页面的模式
webSetting.setLoadWithOverviewMode(true);
// 控制页面显示布局
// NARROW_COLUMNS:可能的话使所有列的宽度不超过屏幕宽度
// NORMAL:正常显示不做任何渲染
// SINGLE_COLUMN:把所有内容放大webview等宽的一列中
webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
//禁止用地理定位
webSetting.setSaveFormData(true);
// 是否启动地理定位
webSetting.setGeolocationEnabled(true);
// 设置定位的数据库路径
webSetting.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");

接下来就是WebView交互中非常重要的两个类WebViewClient和WebChromeClient。WebViewClient就是帮助WebView处理各种通知、请求事件的,具体来说包括以下常用方法:


onLoadResource() // 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。  

shouldOverrideUrlLoading //在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。

onPageStart  //这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。

onPageFinish //在页面加载结束时调用。同样道理,我们知道一个页面载入完成,于是我们可以关闭loading 条,切换程序动作。

onReceiveError // (报告错误信息)

onReceivedHttpAuthRequest ()//(获取返回信息授权请求)

WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 ,常用方法有以下几个:


onCloseWindow()  //关闭WebView

onCreateWindow()  

onJsAlert //WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出)

onJsPrompt  

onJsConfirm  

onProgressChanged //可以根据加载进度设置进度条

onReceivedIcon //可以获取URL icon

onReceivedTitle //可以获取URL title

一、监听a标签

这种实现方式比较简单,我们可以在shouldOverrideUrlLoading中根据URL进行判断,比如说界面中有一个拨打电话的功能,其js代码如下

Android webview与js的数据交互

这里我们可以通过如下方式进行弹出原生dialog


public boolean shouldOverrideUrlLoading(WebView view, String url) {
     if (TextUtils.isEmpty(url))
       return true;
     if (url.startsWith("tel:")) {
       PhoneDialog callDialog = new PhoneDialog(WebViewActivity.this, url);
       callDialog.disDialog();
       callDialog.callPhone();
       callDialog.show();
       return true;
     }
     return true;
   }

二、通过js代码

查了下常用的注入方式有两种,第一种是当webview加载完之后,读取整个js文件中的内容,然后将整个文件内容以字符串的形式,通过webview.loadUrl(“javascript:fileContentString”)注入,不过我好像没怎么用到过这个方式,一般都是用第二种,即通过给特定标签设置事件来满足业务需求。

比如说我们给所有的图片设置一个点击事件来获取图片,进行一些列放大存储等操作,我们可以通过如下代码来实现。


// 注入js函数监听
 private void addImageClickListner() {
   // 这段js函数的功能就是,遍历所有的img几点,并添加onclick函数,函数的功能是在图片点击的时候调用本地java接口并传递url过去
   webView.loadUrl("javascript:(function(){" +
       "var objs = document.getElementsByTagName(\"img\"); " +
       "for(var i=0;i<objs.length;i++) " +
       "{"
       + "  objs[i].onclick=function() " +
       "  { "
       + "    window.imagelistner.openImage(this.src); " +
       "  } " +
       "}" +
       "})()");
 }

// js通信接口
 public class JavascriptInterface {

private Context context;

public JavascriptInterface(Context context) {
     this.context = context;
   }

@android.webkit.JavascriptInterface
   public void openImage(String img) {
     Toast.makeText(context,img,Toast.LENGTH_SHORT).show();
   }
 }
//上述两个方法实现了给图片添加点击事件,我们还需要对webview进行设置以及注入

@SuppressLint({"JavascriptInterface", "NewApi"})
   @Override
   public void onPageFinished(WebView view, String url) {
     view.getSettings().setJavaScriptEnabled(true);
     super.onPageFinished(view, url);
     addImageClickListner();// 页面加载完成之后,添加监听图片的点击js函数
   }
//对WebView进行设置
webView.addJavascriptInterface(new JavascriptInterface(this), "imagelistner");

上述实现方式有以下几点需要注意:1、注意这里的方法名imagelistener要和输入的js代码里面的方法一致,2、自定义的方法openImage一定要注明@Android.webkit.JavascriptInterface,否则不起作用。

可以看到我们注入的js代码是通过getElementsByTagName获取所有的img元素然后设置点击事件,如果我们相对某一特定的元素进行设置也可以通过getElementById获取单独的元素,或者还可以通过getElementsByTagName根据TAG获取元素。

这是我现阶段知道的方式,如果还有其它比较好的实现方式可以一起讨论下。

来源:http://blog.csdn.net/mixin716/article/details/60767561

标签:webview,js,交互
0
投稿

猜你喜欢

  • Java listener简介_动力节点Java学院整理

    2022-12-29 10:02:48
  • kafka的消息存储机制和原理分析

    2022-02-01 13:07:39
  • Java应用层协议WebSocket实现消息推送

    2022-05-09 07:26:29
  • 安卓实现自定义圆形取色盘

    2022-01-14 18:01:55
  • java集合中list的用法代码示例

    2023-04-11 23:29:17
  • C++形参与实参的区别实例解析

    2023-11-02 23:39:05
  • SpringBoot用配置影响Bean加载@ConditionalOnProperty

    2022-11-28 22:16:07
  • C#泛型的逆变协变之个人理解

    2021-05-28 16:33:03
  • JSch教程使用sftp协议实现服务器文件载操作

    2023-10-29 17:43:33
  • Java设计模式之装饰模式详解

    2022-09-27 05:55:32
  • maven资源过滤打包后文件变大的处理方法

    2023-10-05 21:38:24
  • 带着问题读CLR via C#(笔记二)类型基础

    2022-01-31 07:31:08
  • java通过Idea远程一键部署springboot到Docker详解

    2022-03-26 09:31:27
  • Java语言中Swing组件编程详解

    2023-04-19 04:08:22
  • 一文看懂JAVA设计模式之工厂模式

    2023-11-27 02:30:54
  • Java8 用Lambda表达式给List集合排序的实现

    2023-02-05 17:27:09
  • Spring实现默认标签解析流程

    2021-07-29 10:07:55
  • C#利用TreeView控件实现目录跳转

    2021-07-26 02:57:50
  • 详解spring注解式参数校验

    2023-05-08 15:28:52
  • Flutter ListView 上拉加载更多下拉刷新功能实现方法

    2023-06-25 19:51:57
  • asp之家 软件编程 m.aspxhome.com