Android webview与js的数据交互
项目要用到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代码如下
这里我们可以通过如下方式进行弹出原生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获取元素。
这是我现阶段知道的方式,如果还有其它比较好的实现方式可以一起讨论下。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 健康又美味,年轻人的最爱——全麦面包
下一篇: Android实现价格走势自定义曲线图
推荐阅读
-
Android WebView的使用方法及与JS 相互调用
-
Android的WebView与H5前端JS代码交互的实例代码
-
ASP.Net WebAPI与Ajax进行跨域数据交互时Cookies数据的传递
-
JS与OC交互,JS中调用OC方法(获取JSContext的方式)
-
Android APP与媒体存储服务的交互
-
Android中Json数据读取与创建的方法
-
详解 WebView 与 JS 交互传值问题
-
Android开发使用json实现服务器与客户端数据的交互功能示例
-
Android中webview与JS交互、互调方法实例详解
-
Android Webview与ScrollView的滚动兼容及留白处理的方法