前言:
我不会忘了我
忘了我曾说过一定会得到的梦想 ——《老大》小柯

相关文章

1、《WebView使用详解(一)——Native与JS相互调用(附JadX反编译)》
2、《WebView使用详解(二)——WebViewClient与常用事件监听》

###一、WebChromeClient
####1、概述

####(1)、 与WebViewClient的区别
很多同学一看到这里有Chrome,立马就会想到google 的Chrome浏览器;这里并不是指Chrome浏览器的意思,而是泛指浏览器,WebView的内部实现并不是完全使用Chrome的内核,而是部分使用Chome内核,其它都是与Chrome不相同的;
我们再来对比下WebViewClient:

  • WebViewClient:在影响View的事件到来时,会通过WebViewClient中的方法回调通知用户
  • WebChromeClient:当影响浏览器的事件到来时,就会通过WebChromeClient中的方法回调通知用法。

通过上面的对比,我们发现WebViewClient和WebChromeClient都是针对不同事件的回调,而google将这些回调进行分类集合,就产生了WebViewClient、WebChromeClient这两个大类,其中管理着针对不同类型的回调而已。

####(2)、为什么叫WebChromeClient?
因为WebChromeClient中集合了影响浏览器的事件到来时的回调方法,所以这里更需要突出浏览器的概念,而Chrome则是google自家的浏览器名称,所以使用WebChromeClient来做为名称吧,纯属臆想……

####(3)、WebChromeClient的常用函数
我们先来看一下,在WebChromeClient中我们将要讲解的函数,其实WebChromeClient里的函数是非常多的,可以监控到浏览器的很多方面,这里我们就不再一个个来讲了,只讲解常用的几个函数,而且随着ReactNative和Hybird的普及,WebView的使用场景会越来越少,指不定哪一天就被废弃了

/*** 当网页调用alert()来弹出alert弹出框前回调,用以拦截alert()函数*/
public boolean onJsAlert(WebView view, String url, String message,JsResult result)
/*** 当网页调用confirm()来弹出confirm弹出框前回调,用以拦截confirm()函数*/
public boolean onJsConfirm(WebView view, String url, String message,JsResult result)
/*** 当网页调用prompt()来弹出prompt弹出框前回调,用以拦截prompt()函数*/public boolean onJsPrompt(WebView view, String url, String message,String defaultValue, JsPromptResult result) /*** 打印 console 信息*/public boolean onConsoleMessage(ConsoleMessage consoleMessage)/*** 通知程序当前页面加载进度*/public void onProgressChanged(WebView view, int newProgress)

####2、WebChromeClient之onJsAlert、onJsConfirm、onJsPrompt
这一小节我们把这三个函数一起看,因为他们都是为了处理弹出框。
####(1)、为何JS中的alert()、confirm()、prompt()无效
首先,我们来举个例子,在网页中加上按钮,在点击时分别调用alert()、confirm()、prompt()来弹出不同的对话框
web.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1 id="h">欢迎光临启舰的blog</h1><button onclick="confirm('傻叉')">confirm</button><button onclick="alert('傻叉')">alert</button><button onclick="prompt('傻叉')">prompt</button>
</body>
</html>

然后是Java处理代码:(MyActivity.java)

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView)findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.setWebViewClient(new WebViewClient());mWebView.loadUrl("file:///android_asset/web.html");}
}

效果图如下:

从效果图中,虽然启用了JavaScript但是在网页中的confrim()、alert()、prompt()却是没有效果!
这是因为我们需要设置WebChromClient!
在程序中,我们只需要加上mWebView.setWebChromeClient(new WebChromeClient());就可以实现confrim()、alert()、prompt()的弹出效果了
html代码不变,我们来看一下JAVA代码:

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView)findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.setWebViewClient(new WebViewClient());mWebView.setWebChromeClient(new WebChromeClient());mWebView.loadUrl("file:///android_asset/web.html");}
}

相比上面,只多了一句:mWebView.setWebChromeClient(new WebChromeClient());
现在再来看下效果图:

至于为什么会这样,我也不知道,也没仔细去研究它的源码,记住就好了。
####(2)、使用onJsAlert拦截alert()函数概述
我们先来看一下在程序中如何来做的:

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView)findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.setWebViewClient(new WebViewClient());mWebView.setWebChromeClient(new WebChromeClient(){@Overridepublic boolean onJsAlert(WebView view, String url, String message, JsResult result) {Toast.makeText(MyActivity.this,"xxx",Toast.LENGTH_SHORT).show();result.confirm();return true;}});mWebView.loadUrl("file:///android_asset/web.html");}
}

效果图如下:
我们在重写onJsAlert中,在onJsAlert代码中写了三句话:

Toast.makeText(MyActivity.this,"xxx",Toast.LENGTH_SHORT).show();
result.confirm();
return true;

这三句话,句句非常重要:
第一句:

Toast.makeText(MyActivity.this,"xxx",Toast.LENGTH_SHORT).show();

表示我们拦截html中alert函数之后,我们自己的操作,这里是弹出一行toast
第二句:

result.confirm();

这句话非常重要,它表示向WebView通知操作结果,JsResult有两个函数:JsResult.confirm()和JsResult.cancel(),JsResult.confirm()表示点击了弹出框的确定按钮,JsResult.cancel()则表示点击了弹出框的取消按钮。
如果没有使用JsResult来告诉WebView处理结果,则WebView就会认为这个弹出框还一直弹在那里,你再点击alert按钮,将会无效;
第三句:

return true;

表示告诉WebView我们已经拦截了alert()函数,不需要再弹出网页中的alert弹出框了,如果我们return false,那么WebView就会认为我们没有拦截alert()函数,会继续弹出alert对话框。
####(3)、如果onJsAlert没有使用JsResult确认结果
如果我们把result.confirm()去掉,来看一下,是不是真的像我们说的那样再次点击alert按钮会失效

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView)findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.setWebViewClient(new WebViewClient());mWebView.setWebChromeClient(new WebChromeClient(){@Overridepublic boolean onJsAlert(WebView view, String url, String message, JsResult result) {Toast.makeText(MyActivity.this,"xxx",Toast.LENGTH_SHORT).show();
//                result.confirm();return true;}});mWebView.loadUrl("file:///android_asset/web.html");}
}

我们把上面代码中的 result.confirm()给注掉一下,看下效果:

从效果图中可以看到,在去掉 result.confirm()以后,只有第一次有效果,后面再点击alert按钮就无效了(动画中看不出来点击效果,其实我一直在点……)。
####(4)、如果onJsAlert中return false会怎样
前面我们也讲到,如果在onJsAlert中return true,则表示告诉WebView我们已经拦截了alert函数,系统不需要再弹出alert对话框了,如果return false,则表示告诉WebView我们没有拦截alert函数,使用系统的默认处理,从WebChromeClient的源码中可以看到onJsAlert默认是return false的。

public boolean onJsAlert(WebView view, String url, String message,JsResult result) {return false;
}

下面我们就来看看如何我们在弹出toast以后return false,系统是不是真的还会弹出alert对话框

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView)findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.setWebViewClient(new WebViewClient());mWebView.setWebChromeClient(new WebChromeClient(){@Overridepublic boolean onJsAlert(WebView view, String url, String message, JsResult result) {Toast.makeText(MyActivity.this,"xxx",Toast.LENGTH_SHORT).show();result.confirm();return false;}});mWebView.loadUrl("file:///android_asset/web.html");}
}

效果图如下:

从效果图中也明显看出了我们的结论是正确的,当return false时,不管我们前面做了什么,依然会弹出对话框。

好了,有关onJsAlert我们总结一下:

  • 如果需要使网页中的confrim()、alert()、prompt()函数生效,需要设置WebChromeClient!
  • 在使用onJsAlert来拦截alert对话框时,如果不需要再弹出alert对话框,一定要return true;在return false以后,会依然调用系统的默认处理来弹出对话框的
  • 如果我们return true,则需要在处理完成以后调用JsResult.confirm()或者JsResult.cancel()来告诉WebView我们点中哪个按钮来取消程序对话框。否则再次点击按钮将会失败

可能有些同学不知道confrim(),prompt()的对话框效果,下面就整体给大家演示一下html中原生的效果。

有关confrim()和prompt()的拦截,我们就不再讲了,与拦截alert()一样!
####3、WebChromeClient之onConsoleMessage
当html中调用console相关输出的时候,就会通过onConsoleMessage进行通知

public boolean onConsoleMessage(ConsoleMessage consoleMessage)

参数意义:

  • ConsoleMessage consoleMessage:保存着当前消息的类型和消息内容
  • 返回值:如果返回true时,就表示拦截了console输出,系统就不再通过console输出出来了,如果返回false则表示没有拦截console输出,调用系统默认处理。

我们来看下正常情况下,console输出的内容及用法
先来看html内容:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1 id="h">欢迎光临启舰的blog</h1><button onclick="confirm('傻叉')">confirm</button><button onclick="alert('傻叉')">alert</button><button onclick="prompt('傻叉')">prompt</button><button onclick="log()">log</button>
</body>
<script type="text/javascript">
function log(){console.log("console.log");console.warn("warnning");console.error("error");
}
</script>
</html>

对应的java代码如下:

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView)findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.setWebViewClient(new WebViewClient());mWebView.loadUrl("file:///android_asset/web.html");}
}

除了alert,prompt,confirm以外,其它时候都不需要强制设置WebChromeClient
当点击log按钮时,会调用console的函数把log输出出来
效果图如下:

在我们logcat中也可以看到如下日志:

####示例:拦截Console,弹出消息
下面我们就重写WebChromeClient的onConsoleMessage方法,把console消息拦截掉,然后把消息利用toast弹出来:

mWebView.setWebChromeClient(new WebChromeClient(){@Overridepublic boolean onConsoleMessage(ConsoleMessage consoleMessage) {Toast.makeText(MyActivity.this,consoleMessage.message(),Toast.LENGTH_SHORT).show();return  true;}});

效果图如下:

由于我们return true,控制台将不会再看到我们的消息日志了。
####4、WebChromeClient之onProgressChanged
表示当前页面的加载速度,函数声明如下:

public void onProgressChanged(WebView view, int newProgress)
  • WebView view:当前WebView实例
  • int newProgress:当前的加载进度,值从0到100

比如我们加载“http://blog.csdn.net/harvic880925”
然后把加载进度用日志打出来:

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView)findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.setWebViewClient(new WebViewClient());mWebView.setWebChromeClient(new WebChromeClient(){@Overridepublic void onProgressChanged(WebView view, int newProgress) {Log.e("qijian","progress:"+newProgress);super.onProgressChanged(view, newProgress);}});mWebView.loadUrl("http://blog.csdn.net/harvic880925");}
}

日志如下:

大家一定要注意,底层实现时,是利用handler来定时轮循当前进度的,每隔一定时间查询一次,所以每次拿到的进度数据是不一样的,也就是说如果页面较简单,可能会直接返回100,而跳过中间的各个数据。也就是说,除了100,其它任何一个数值不是一定返回的,所以大家如果要用到进度除了数值100可以用等号来判断,其它一定要用大于号或小于号,如果用了等号,可能永远也不会执行到!
####5、WebChromeClient之其它函数
WebChromeClient除了上面几个常用函数以后,还有其它一些函数,下面就简单列举一下,就不再一一举例了

/*
* 通知页面标题变化
*/
nReceivedTitle(WebView view, String title)/*
* 通知当前页面网站新图标
*/
onReceivedIcon(WebView view, Bitmap icon)/*
* 通知主程序图标按钮URL
*/
onReceivedTouchIconUrl(WebView view, String url, boolean precomposed)/*
* 通知主程序当前页面将要显示指定方向的View,该方法用来全屏播放视频。
*/
public interface CustomViewCallback {// 通知当前页面自定义的View被关闭public void onCustomViewHidden();}
onShowCustomView(View view, CustomViewCallback callback)/*
* 与onShowCustomView对应,通知主程序当前页面将要关闭Custom View
*/
onHideCustomView()/*** 请求主程序创建一个新的Window,如果主程序接收请求,返回true并创建一个新的WebView来装载Window,然后添加到View中,发送带有创建的WebView作为参数的resultMsg的给Target。如果主程序拒绝接收请求,则方法返回false。默认不做任何处理,返回false*/
onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)/*
* 显示当前WebView,为当前WebView获取焦点。
*/
onRequestFocus(WebView view)/*
* 通知主程序关闭WebView,并从View中移除,WebCore停止任何的进行中的加载和JS功能。
*/
onCloseWindow(WebView window)/*** 告诉客户端显示离开当前页面的导航提示框。如果返回true,由客户端处理确认提示框,调用合适的JsResult方法。如果返回false,则返回默认值true给javascript接受离开当前页面的导航。默认:false。JsResult设置false,当前页面取消导航提示,否则离开当前页面。*/
onJsBeforeUnload(WebView view, String url, String message, JsResult result)/***通知主程序web内容尝试使用定位API,但是没有相关的权限。主程序需要调用调用指定的定位权限申请的回调。更多说明查看GeolocationPermissions相关API。*/
onGeolocationPermissionsShowPrompt(String origin,GeolocationPermissions.Callback callback)/** 通知程序有定位权限请求。如果onGeolocationPermissionsShowPrompt权限申请操作被取消,则隐藏相关的UI界面。*/
onGeolocationPermissionsHidePrompt()/**
*通知主程序web内容尝试申请指定资源的权限(权限没有授权或已拒绝),主程序必须调用PermissionRequest#grant(String[])或PermissionRequest#deny()。如果没有覆写该方法,默认拒绝。
*/
onPermissionRequest(PermissionRequest request)/**
* 通知主程序相关权限被取消。任何相关UI都应该隐藏掉。
*/
onPermissionRequestCanceled(PermissionRequest request)/**
* 通知主程序 执行的Js操作超时。客户端决定是否中断JavaScript继续执行。如果客户端返回true,JavaScript中断执行。如果客户端返回false,则执行继续。注意:如果继续执行,重置JavaScript超时计时器。如果Js下一次检查点仍没有结束,则再次提示。
*/
onJsTimeout()/**
*当停止播放,Video显示为一张图片。默认图片可以通过HTML的Video的poster属性标签来指定。如果poster属性不存在,则使用默认的poster。该方法允许ChromeClient提供默认图片。
*/
getDefaultVideoPoster()/**
* 当用户重放视频,在渲染第一帧前需要花费时间去缓冲足够的数据。在缓冲期间,ChromeClient可以提供一个显示的View。如:可以显示一个加载动画。
*/
getVideoLoadingProgressView()/**
* 获取访问历史Item,用于链接颜色。
*/
getVisitedHistory(ValueCallback callback)/**
* 通知客户端显示文件选择器。用来处理file类型的HTML标签,响应用户点击选择文件的按钮操作。调用filePathCallback.onReceiveValue(null)并返回true取消请求操作。
* FileChooserParams参数的枚举列表:
MODE_OPEN 打开
MODE_OPEN_MULTIPLE 选中多个文件打开
MODE_OPEN_FOLDER 打开文件夹(暂不支持)
MODE_SAVE 保存
*/
onShowFileChooser(WebView webView, ValueCallback filePathCallback,FileChooserParams fileChooserParams)/**
* 解析文件选择Activity返回的结果。需要和createIntent一起使用。
*/
parseResult(int resultCode, Intent data)/**
* 创建Intent对象来启动文件选择器。Intent支持可访问的简单类型文件资源。不支持高级文件资源如live media capture媒体快照。如果需要访问这些资源或其他高级文件类型资源可以自己创建Intent对象。
*/
createIntent()/**
* 返回文件选择模式
*/
getMode()/**
* 返回可访问MIME类型数组,如audio/*,如果没有指定可访问类型,数组返回为null
*/
getAcceptTypes()/**
* 返回优先的媒体快照类型值如Camera、Microphone。true:允许快照。false,禁止快照。使用getAcceptTypes方法确定合适的capture设备。
*/
isCaptureEnabled()/**
* 返回文件选择器的标题。如果为null,使用默认名称。
*/
getTitle()/**
*指定默认选中的文件名或为null
*/
getFilenameHint()

###二、LoadData()与loadDataWithBaseURL()
在第一篇中,我们就已经讲了通过loadUrl()来加载本地页面和在线地址的方式,这里给大家再补充两个方法LoadData()与loadDataWithBaseURL(),它们不是用来加载整个页面文件的,而是用来加载一段代码片的。这两个函数平时用的比较少,这里只讲基本用法,就不再深入了。
声明方式为:

public void loadData(String data, String mimeType, String encoding)
public void loadDataWithBaseURL(String baseUrl, String data,String mimeType, String encoding, String historyUrl)

这里每个参数的具体意义后面再详细讲解,这里涉及到MIME类型,我以前有篇文章讲过,大家可以参考下:《 ContentProvider数据库共享之——MIME类型与getType()》
简单来讲,MIME的类型格式是跟文件的后缀相关联的,比如下面的几个关联方式:

文件后缀 MIME类型
html text/html
jpg image/jpeg
bmp image/bmp
png image/png

这里仅涉及到网页和图片的类型,还有其它的文件后缀和对应的MIME类型,这里就不再一一列举了,有关MIME类型的具体意义大家可以参考上面的文章。
####1、loadData
####示例1:简单使用
我们先来看看loadData是如何使用的,它的声明如下:

public void loadData(String data, String mimeType, String encoding)
  • String data:代码片段内容
  • String mimeType:代码片段所对应的MIME类型,如果传null,则默认为text/html
  • String encoding:代码片段的编码方式

我们先举个例子来看下:

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView) findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.getSettings().setDefaultTextEncodingName("utf-8");String summary = "<html><body>You scored <b>192</b> points.</body></html>";mWebView.loadData(summary, "text/html", "utf-8");}
}

效果图为:

这段代码很简单,就不再讲了。
####示例2:loadData的正确使用方式
在使用loadData时,在数据里面不能出现英文字符:’#’, ‘%’, ‘’ , ‘?’ 这四个字符,如果有的话可以用 %23, %25, %27, %3f,这些字符来替换,在平时测试时,你的数据时,你的数据里含有这些字符,但不会出问题,当出问题时,你可以替换下。
直接使用这四个字符会造成的问题如下:

  • %:会报找不到页面错误,页面全是乱码。
  • #,会让你的goBack失效,但canGoBAck是可以使用的。于是就会产生返回按钮生效,但不能返回的情况。
  • \ 和? 我在转换时,会报错,因为它会把\当作转义符来使用,如果用两级转义,也不生效,我是对它无语了。

我们虽然可以把代码中的字符逐个读取,然后给转换掉,但运行速度上会大打折扣,因为webview.loadData()是运行在主线程的,所以如果你的代码段很长,那就会卡死主线程!所以Android给我们提供了一个专门用来转码的函数:URLEncoder.encode(String s, String charsetName),它能将冲突的字符进行转义,然后再传给webview,这样webview在加载时就不会有冲突了,encode函数的声明如下:

public static String encode(String s, String charsetName);
  • String s:代码段
  • String charsetName:编码类型

下面我们来看使用这个encode函数的例子:

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView) findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.getSettings().setDefaultTextEncodingName("utf-8");try {String summary = "<html><body>You scored <b>192</b> points.</body></html>";mWebView.loadData(URLEncoder.encode(summary, "utf-8"), "text/html", "utf-8");} catch (Exception e) {Log.e("qijian", e.getMessage());}}
}

data中,有人会遇到中文乱码问题,解决办法:参数传"utf-8",页面的编码格式也必须是utf-8,这样编码统一就不会乱了。别的编码我也没有试过。

注意:
1、loadData()应该是不能加载图片的,反正我是加载不出来,加载图片的内容我们后面会使用loadDataWithBaseURL来实现。
2、为了防止字符冲突,在传递loadData的数据时,必须使用URLEncoder.encode()函数来转义
3、页面的编码格式必须与代码中传参的编码格式一致,不然会导致乱码

####2、loadDataWithBaseURL
相比loadData,这个函数更常用,因为loadData能实现的功能,它都能实现,而且也不会出现字符冲突。其函数声明如下:

public void loadDataWithBaseURL(String baseUrl, String data,String mimeType, String encoding, String historyUrl)

参数意义如下:

  • String baseUrl:基准URL,不需要可以传null,它的意思是,如果data中的url是相对地址,则就会加上基准url来拼接出完整的地址,比如baseUrl是http://img6.ph.126.net,data中有个Img标签,它的内容是:<img src='hBiG96B8egigBULxUWcOpA==/109212290980771276.jpg'>,很明显src的地址不是本地地址也不是在线地址,那它就是一个相对地址,所以加上baseUrl以后才是它的完整地址:http://img6.ph.126.net/hBiG96B8egigBULxUWcOpA==/109212290980771276.jpg
  • String mimeType:MIME类型
  • String encoding:编码方式
  • String historyUrl:当前的历史记录所要存储的值。如果不需要可以传Null,loadDataWithBaseURL它本身并不会向历史记录中存储数据,要想实现历史记录,需要我们自己来实现;有关历史记录的实现方式是比较复杂的,历史记录是以Key/value的方式存储在一个historyList里的,当前进后退时,会用Key来取出对应的value值来加载进webview中。而Key就是这里的baseUrl,Value就是这里的historyUrl;history所指向的必须是一个页面,并且页面存在于SD卡中或程序中(assets);

下面我们举个例子来看下baseUrl的概念:
####示例1:baseUrl的用法

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView) findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.getSettings().setDefaultTextEncodingName("utf-8");String baseURL = "http://img6.ph.126.net";String data = "漂亮MM <img src='hBiG96B8egigBULxUWcOpA==/109212290980771276.jpg'>";mWebView.loadDataWithBaseURL(baseURL, data, "text/html", "utf-8", null);}
}

效果图如下:

####示例2:三种地址加载情况
我们再进阶一下,看如果网页地址是绝对地址,本地文件地址也是绝对地址,而另外一个是相对地址的情况下,看baseUrl是如何操作的

public class MyActivity extends Activity {private WebView mWebView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mWebView = (WebView) findViewById(R.id.webview);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.getSettings().setDefaultTextEncodingName("utf-8");String baseURL = "http://img6.ph.126.net";String data = "绝对网页地址:" +"<img src='http://img3.3lian.com/2013/v8/72/d/61.jpg'>" +"本地地址:" +"<img src='file:///android_asset/s07.jpg'>" +"相对地址:" +"<img src='hBiG96B8egigBULxUWcOpA==/109212290980771276.jpg'>";mWebView.loadDataWithBaseURL(baseURL, data, "text/html", "utf-8", null);}
}

效果图如下:

在代码中有三种地址:第一个是绝对的http地址,第二个是通过file指定的本地地址,对于这两类的绝对地址,baseUrl是不起作用的,而对于第三个相对地址,是会启用baseUrl的来拼接完整地址的。

总结:

  • 面这两种方法,我建议使用后者,虽然loadData的历史记录不需要我们自己来实现,但在使用时,这就两个加载上后者比前者快一到两倍。
  • 另外loadData不能加载图片,而loadDataWithBaseURL是可以加载图片的

好了,这篇就到这里了,有关WebView系列就先到这了,下篇继续写自定义控件……
源码在文章底部给出

如果本文有帮到你,记得加关注哦

源码下载地址:http://download.csdn.net/detail/harvic880925/9540930
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/51583253 谢谢


如果你喜欢我的文章,你可能更喜欢我的公众号


WebView使用详解(三)——WebChromeClient与LoadData补充相关推荐

  1. Android WebView 开发详解(三)

    转载请注明出处   http://blog.csdn.net/typename/article/details/40302351 powered by miechal zhao 概览 Android ...

  2. WebView使用详解之WebChromeClient的常用事件监听

    一.WebChromeClient 1.概述 (1). 与WebViewClient的区别 很多同学一看到这里有Chrome,立马就会想到google 的Chrome浏览器:这里并不是指Chrome浏 ...

  3. WebView使用详解(一)——Native与JS相互调用(附JadX反编译)

    前言:念念不忘,必有回响,永远坚持你所坚持的! 相关文章: 1.<WebView使用详解(一)--Native与JS相互调用(附JadX反编译)> 2.<WebView使用详解(二) ...

  4. Android WebView 开发详解(二)

    转载请注明出处  http://blog.csdn.net/typename/article/details/39495409powered by miechal zhao 概览: Android W ...

  5. Carson带你学Android:最全面的Webview使用详解

    前言 现在很多App里都内置了Web网页(Hyprid App),比如说很多电商平台,淘宝.京东.聚划算等等,如下图 那么这种该如何实现呢?其实这是Android里一个叫WebView的组件实现的.今 ...

  6. Android init.rc文件解析过程详解(三)

    Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...

  7. linux 进程间通信 dbus-glib【实例】详解三 数据类型和dteeth(类型签名type域)(层级结构:服务Service --> Node(对象、object) 等 )(附代码)

    linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...

  8. Windows 7防火墙设置详解(三)

    Windows 7防火墙设置详解(三) 一.如何禁用或启用规则 方法:只需要在需要禁用或启动的规则上,鼠标右键选择启用或禁止规则即可,或点击右侧的操作栏进行规则启用或禁止. 二.入站规则和出站规则 由 ...

  9. Android Studio 插件开发详解三:翻译插件实战

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78113868 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...

最新文章

  1. 通过神经图稳定对脑机接口的即插即用控制,四肢瘫痪患者可以轻松控制电脑光标...
  2. 常使用的webserver地址
  3. nginx 配置 http/2(h2) 和 http 在同一端口的问题
  4. linux mysql自动备份 和 数据恢复
  5. BZOJ 3729: Gty的游戏 [伪ETT 博弈论]【学习笔记】
  6. Java软件开发工程师简历模板包装教学问题完整版 【心静思远-9527】
  7. android代码 发警报音,Android设置多个警报
  8. python输入球的半径计算球的表面积和体积_球扇形(球心角体)体积,表面积计算公式与在线计算器_三贝计算网_23bei.com...
  9. ESP8266便携式物联网时钟(硬件篇) 代号:喵
  10. 2023年最新微信小程序获取用户openid、头像昵称的填写能力和方法原生写法
  11. NAT配置两台Ubuntu通网
  12. python爬虫登录网站_主流网站 Python 爬虫模拟登陆方法汇总
  13. 7-11正式进军柬埔寨;2021年全球乳业排行榜公布;麦咖啡跨界多芬推出新品 | 食品饮料新品...
  14. 拍照 识别 翻译 云脉慧眼
  15. 进入Sic-Hub的办法
  16. 警惕:信用卡分期陷阱
  17. 使用.Net Core+Vue打造企业通用管理端
  18. 多边形内角和c语言编程,多边形的内角和与外角和同步练习题
  19. 大数据如何助力营销(3)产品定位
  20. 我常用的Vim和Bash配置

热门文章

  1. 面对“有组织有预谋”的欺诈行为,技术大牛都祭出了哪些新技术?...
  2. Python 判断操作系统类型
  3. SpringBoot快速实现微信授权登录
  4. 说说ESXi虚拟交换机和端口组的“MAC地址更改”和“伪传输”
  5. 江西学校计算机排名2015年,江西截止2021年共计107所大学,排名前22名是这些院校...
  6. 南宁陶粒之慢性病监测信息管理系统功能技术分享
  7. MySQL索引与索引优化
  8. Java related——Tomcat安装教程(赶快拥有一只自己的汤姆猫吧)
  9. OpenCV-Python 彩色图
  10. 北京奥特易雨量灯光传感器