Android中WebView使用全解
开始
在Android系统中内嵌的WebKit,这是一个浏览器内核,它帮助着我们可以浏览网页。在实际开发中,如果你想让你的App能够访问网页,那就需要用到WebView这个控件。
如何使用?
其实使用起来很简单,通常情况下我们会在布局XML中写入这个控件之后在Activity中进行调用:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/web">
Activity/Fragment中:
WebView webView = (WebView) findViewById(R.id.web);
webView.loadUrl("https://lovelyyakir.github.io");
运行一下就能看到这样的效果:

使用进阶
webView的跳转和返回
在实际使用中你会发现,有时候我们需要点击网页中的某个链接进行网页跳转,而系统会默认加载自带浏览器,而不是我们的WebView。如果你想要让WebView跳转那又该怎么做呢?
其实很简单,我们只需要给WebView设置一个webClient,并且重写里面的shouldOverrideUrlLoading()就能很简单的实现啦。
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
谷歌工程师给我们提供了两个参数,我们需要调用load方法传入url,并且需要在返回值中返回true。允许在本WebView中进行跳转。当我们点击返回,你会发现程序退出了。当然这不是
我们想要的结果。所以我们需要在Activity中重写onKeyDown(),进行判断,当我们的页面可以返回时点击返回,返回上一个界面,无法返回执行其他操作或者退出。
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (webView.canGoBack()&&keyCode==KeyEvent.KEYCODE_BACK) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode,event);
}
便是这个效果:

强制关闭某个Web界面
在Native与H5交互完成的情况之下,我们需要主动关闭当前的WebView回到原生界面,这时候又该如何处理呢?其实解决途径有很多这里介绍两种解决方法:
1.我们可以监听到最后的网页的Url获取Url之后通过字符串匹配的方式关闭当前界面,你可以在WebClient中重写下面这个方法,将跳转的URL取出来。
@Override
public voidonLoadResource(WebViewview,Stringurl){
//监听到进入了关闭页面就把activity关闭
LogUtil.e("跳转的url:"+url);
}
通过匹配字符串做相应的操作。
2.通过控制台获取相关的信息,根据信息做相应操作。
webView.setWebChromeClient(newWebChromeClient(){
@Override
public boolean onConsoleMessage(ConsoleMessageconsole Message){
LogUtil.e(consoleMessage.message());
if("success".equals(consoleMessage.message())||"close window".equals(consoleMessage.message())){
finish();
}
return super.onConsoleMessage(consoleMessage);
}
});
通过WebView的setChromClient重写onConsoleMessage通过相关的信息做相应的操作。
进阶操作
WebView与Javascript进行交互
在实际开发中,调用webview,我们希望能与其他其他网页进行交互。非原生界面调用原生方法,原生界面调用非原生方法。(WebView与Javascript相互调用)。
1.Javascript调用Java原生代码
我们先看一段Javascript的代码:
$("#test1").click(function(e){window.injs.takeFrontIDCardCamera();});
$("#test2").click(function(e){window.injs.takeBackIDCardCamera();});
$("#test3").click(function(e){window.injs.takeFaceCamera();});
这里表示三个Javascript点击事件,window.injs.takeFaceCamera();这行代码中window表示窗口,injs表示作用域,紧跟着的就是方法名了。我们需要让WebView允许和Javascript进行交互,并且绑定作用域。
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(this,"injs");
最后重写Javascript方法:
@JavascriptInterface
public void takeFrontIDCardCamera() {
Toast.makeText(this,"Native get takeFrontIDCardCamera",Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void takeBackIDCardCamera() {
Toast.makeText(this,"Native get takeBackIDCardCamera",Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void takeFaceCamera() {
Toast.makeText(this,"Native get takeFaceCamera",Toast.LENGTH_SHORT).show();
}
Javascript调用原生方法时弹出一个土司验证

2.原生界面调用Javascript
下面展示几个Javascript本地方法
function jhjcardfontjs(font){
alert(font);
}
function jhjcardbackjs(back){
alert(back);
}
function jhjfacejs(face){
alert(face);
}
调用无参的方法时只需要在webview的load方法中写入javascript:你的方法()。像这样:
webView.loadUrl("javascript:jhjcardfontjs()");
如果有参数要注意,脚本中会有转义符需要处理一下再传入:
String var="";
var=var.replaceAll("\\\\", "\\\\\\\\");
webView.loadUrl("javascript:jhjcardfontjs('" + var + "')");
登陆Session同步
用户通过原生App进行登录,之后进行某些操作到H5界面,这个时候原生界面和H5界面的登陆状态不同,为了防止用户再次登陆造成的用户体验问题,我们需要让WebView同步我们原声界面的Session让用户不用重新登陆。
1.获取用户登录信息Cookie,你可以通过你使用的网络请求框架获取Cookie。这里我使用OkHttp获取我的Cookie信息,之后将这个信息保存起来:
Listcookies=OkHttpUtils
.getInstance()
.getOkHttpClient()
.cookieJar()
.loadForRequest(HttpUrl.parse(SysConfig.myFinalUrl(SysConfig.loginUrl)));
for(Cookiecookie:cookies){
//保存在内存当中
if(!cookie.value().contains("dk")){
Constant.appCookie=cookie;
}
}
2.在WebView中加载他:
CookiesessionCookie=Constant.appCookie;//这里的cookie就是上面保存的cookie
CookieSyncManager.createInstance(this);
CookieManagercookieManager=CookieManager.getInstance();
if(sessionCookie!=null){
cookieManager.removeSessionCookie();
StringcookieString=sessionCookie.name()+"="+sessionCookie.
value()+"; domain="+sessionCookie.domain();
cookieManager.setCookie(sessionCookie.domain(),cookieString);
CookieSyncManager.getInstance().sync();
wbQrContent.setWebViewClient(newWebViewClient(){
@Override
public booleanshouldOverrideUrlLoading(WebViewview,Stringurl){
view.loadUrl(url);
return true;
}
});
}
补充
1.WebViewClient和WebChromeClient有什么不同?
WebViewClient主要帮助WebView处理各种通知、请求事件而如果你想处理js、进度条等,就要用到WebChromeClient。他们的区别在于功能的区别。
2.为什么我调用JS修改原生UI报错了?
如果你在JavaScript中调用原生方法修改Ui,你需要确保这个方法执行在主线程。这是由于JavaBridge并不在主线程中。(你可以使用hander,runOnUiThread,Rxjava)
Android中WebView使用全解的更多相关文章
- Android中webView和网页的交互
Android中webView和网页的交互 Android中webView跟网页的交互式通过JavaScript进行的.具体步骤: 1.创建JavaScript,在点击的时候调用JavaScript ...
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
- Android中mesure过程详解
我们在编写layout的xml文件时会碰到layout_width和layout_height两个属性,对于这两个属性我们有三种选择:赋值成具体的数值,match_parent或者wrap_conte ...
- Android中Intent组件详解
Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件.Intent本身是定义为一个类别(Class),一个Intent对象表达一个目的(Goal)或期望(Expectation),叙 ...
- Android中WebView的JavaScript代码和本地代码交互的三种方式
一.Android中WebView的漏洞分析最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视 ...
- Android 中Webview 自适应屏幕
随笔 - 478 文章 - 3 评论 - 113 Android 中Webview 自适应屏幕 webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomCon ...
- Android中的动画详解系列【4】——Activity之间切换动画
前面介绍了Android中的逐帧动画和补间动画,并实现了简单的自定义动画,这一篇我们来看看如何将Android中的动画运用到实际开发中的一个场景--Activity之间跳转动画. 一.定义动画资源 如 ...
- android 中webview的屏幕适配问题
两行代码解决WebView的屏幕适配问题 一个简单的方法,让网页快速适应手机屏幕,代码如下 1 2 WebSettings webSettings= webView.getSettings(); we ...
- Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)
一.前言 去年年底支付宝的被克隆漏洞被爆出,无独有偶就是腾讯干的,其实真正了解这个事件之后会发现,感觉是针对支付宝.因为这个漏洞找出肯定花费了很大劲,主要是因为支付宝的特殊业务需要开启了WebView ...
随机推荐
- 2013-7-28 802.11n帧聚合
芯片开发阶段的帧聚合迥异于商用AP,前者更偏向实现过程,后者偏向结果.也就是说用户在使用商用设备时不会管你特性是如何实现的,他们只关心效果,开启这个功能能否实实在在的提高AP的吞吐量. 网上搜索了众多 ...
- 解决Qt Creator下 undefined reference to 'qmain(int,char**)'的问题
Qt Creator运行以下程序: #include <QTextStream> #include <QList> int main(void) { QTextStream o ...
- shell脚本函数
不调用就不执行 调用就执行 调用时候的$1是指执行时候的参数1 调用之后的$是位置参数
- 【Codeforces】CF 8 C Looking for Order(状压dp)
题目 传送门:QWQ 分析 这种题不会做 吃枣药丸..... 想到状压已经经过的点. 然后更新时枚举两个点加进去. 复杂度$ {O(2^n \times n^2)}$. 凉凉. 真正的做法是每一个状 ...
- js的数组操作相关(BigTree*)
JavaScript中创建数组有两种方式 (一)使用 Array 构造函数: var arr1 = new Array(); //创建一个空数组var arr2 = new Array(20); // ...
- Phoenix 安装完的几个简单使用
Phoenix 安装完之后的一些简单使用: 本屌丝的运行环境是3节点集群,先启动hadoop,每个节点分别启动zookeeper,启动hbase(具体怎么启动这里就不多说了) 进入 phoenix的b ...
- 深度学习、图像识别入门,从VGG16卷积神经网络开始
刚开始接触深度学习.卷积神经网络的时候非常懵逼,不知道从何入手,我觉得应该有一个进阶的过程,也就是说,理应有一些基本概念作为奠基石,让你有底气去完全理解一个庞大的卷积神经网络: 本文思路: 一.我认为 ...
- video元素和audio元素
内容: 1.video元素 2.audio元素 注:这两个元素均是HTML5新增的元素 1.video元素 (1)用途 <video> 标签定义视频,比如电影片段或其他视频流 (2)标签属 ...
- shell中使用函数
函数定义.调用 $ cat te.sh #!/bin/bash # define a function test() { echo "This is a function." } ...
- UVA-839-二叉树-一个有意思的题目
题意: 一颗二叉树可以看成一个杠杆,左右俩边有重量,有到支点长度,判断整个树是否平衡(根据杠杆原理),如果当前结点有左孩子,那么当前左边的重量就是左孩子的总和,右边同理 递归,发现scanf和cin的 ...