开始

在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");

运行一下就能看到这样的效果:

1-1

使用进阶

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);

}

便是这个效果:

1-2

强制关闭某个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调用原生方法时弹出一个土司验证

1-3

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使用全解的更多相关文章

  1. Android中webView和网页的交互

     Android中webView和网页的交互 Android中webView跟网页的交互式通过JavaScript进行的.具体步骤: 1.创建JavaScript,在点击的时候调用JavaScript ...

  2. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

  3. Android中mesure过程详解

    我们在编写layout的xml文件时会碰到layout_width和layout_height两个属性,对于这两个属性我们有三种选择:赋值成具体的数值,match_parent或者wrap_conte ...

  4. Android中Intent组件详解

    Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件.Intent本身是定义为一个类别(Class),一个Intent对象表达一个目的(Goal)或期望(Expectation),叙 ...

  5. Android中WebView的JavaScript代码和本地代码交互的三种方式

    一.Android中WebView的漏洞分析最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视 ...

  6. Android 中Webview 自适应屏幕

    随笔 - 478  文章 - 3  评论 - 113 Android 中Webview 自适应屏幕   webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomCon ...

  7. Android中的动画详解系列【4】——Activity之间切换动画

    前面介绍了Android中的逐帧动画和补间动画,并实现了简单的自定义动画,这一篇我们来看看如何将Android中的动画运用到实际开发中的一个场景--Activity之间跳转动画. 一.定义动画资源 如 ...

  8. android 中webview的屏幕适配问题

    两行代码解决WebView的屏幕适配问题 一个简单的方法,让网页快速适应手机屏幕,代码如下 1 2 WebSettings webSettings= webView.getSettings(); we ...

  9. Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)

    一.前言 去年年底支付宝的被克隆漏洞被爆出,无独有偶就是腾讯干的,其实真正了解这个事件之后会发现,感觉是针对支付宝.因为这个漏洞找出肯定花费了很大劲,主要是因为支付宝的特殊业务需要开启了WebView ...

随机推荐

  1. bzoj 4911: [Sdoi2017]切树游戏

    考虑维护原树的lct,在上面dp,由于dp方程特殊,均为异或卷积或加法,计算中可以只使用fwt后的序列 v[w]表示联通子树的最浅点为w,且不选w的splay子树中的点 l[w]表示联通子树的最浅点在 ...

  2. springMVC学习(2)

    一.使用注解的处理器映射器和适配器 1) 在这个下面的/org/springframework/web/servlet/DispatcherServlet.properties文件,从这个文件中加载处 ...

  3. [转]预编译 ASP.NET 网站

    转自:如何:预编译 ASP.NET 网站 Visual Studio 2005   预编译 ASP.NET 网站可缩短用户的初始响应时间,因为页在第一次被请求时无需编译.这对于经常更新的大型网站尤其有 ...

  4. MySQL工具 Navicat

    F6打开命令行窗口 ctrl+shift+r  运行选中语句   #不过不建议使用,因为ctrl+r是执行当前所有语句,如果语句当中有delete update 后果不堪设想

  5. 设置UMG的ComboBox(String)字体大小

    转自:http://aigo.iteye.com/blog/2295448 UMG自带ComboBox组件没有提供直接的属性来修改其字体大小,只能自己做一个列表类型的widget然后再塞进ComboB ...

  6. Eclipse中安装及配置EGit插件

    转载:https://jingyan.baidu.com/article/59703552dcc5ad8fc107407e.html

  7. CGLib缺少jar出现 java.lang.ClassNotFoundException: org.objectweb.asm.Type

    CGLib实现动态代理区别于JDK动态代理,不需要目标类实现任何接口,是通过生成代理类子类的方式,而且据说速度要快于JDK动态代理.所以我想要试验一下CGlib的动态代理,网上找了些例子,自己动手写了 ...

  8. Hadoop 2.7.3 分布式集群安装

    1. 集群规划: 192.168.1.252 palo252 Namenode+Datanode 192.168.1.253 palo253 YarnManager+Datanode+Secondar ...

  9. sqoop操作之HDFS导出到ORACLE

    注意:在导出前需要先创建待导出的表结构.如果导出的表在数据库中不存在则会报错:如果重复导出多次,表中的数据会重复: ; ; 导出表的所有字段 sqoop export --connect jdbc:o ...

  10. python之socket编写

    Socket 类型 套接字格式: socket(family,type[,protocal]) 使用给定的地址族.套接字类型.协议编号(默认为0)来创建套接字. socket类型 描述 socket. ...