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

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

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信息,之后将这个信息保存起来:

List cookies=OkHttpUtils

.getInstance()

.getOkHttpClient()

.cookieJar()

.loadForRequest(HttpUrl.parse(SysConfig.myFinalUrl(SysConfig.loginUrl)));

for(Cookie cookie:cookies){

//保存在内存当中

if(!cookie.value().contains("dk")){

Constant.appCookie=cookie;

}

}


2.在WebView中加载他:

Cookiesession Cookie=Constant.appCookie;//这里的cookie就是上面保存的cookie

CookieSyncManager.createInstance(this);

CookieManage rcookieManager=CookieManager.getInstance();

if(sessionCookie!=null){

cookieManager.removeSessionCookie();

Stringcookie String=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)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容