本篇文章作为我对WebView使用过程中的一个总结。
1.WebView基本使用。在app中显示在线网址。
设置权限
<uses-permissionandroid:name="android.permission.INTERNET"/>```
写布局文件
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>```
在Acitvity中mWebView.loadUrl(url);
//这种写法应用启动后会开启手机内置浏览器
要想在应用中打开网页,需要我们在调用loadUrl前加上如下这句。
mWebView.setWebViewClient(new WebViewClient());
访问www.baidu.com。干净简洁没新闻,没广告。但是记得我们的url需要写成http://www.baidu.com。 WebView是不会添加头的。
上面我们使用WebViewClient这个类,之后根据问题再介绍。
2.在网页没出来之前显示一片空白,怎样知道网页加载的速度。
更改布局,在LinearLayout布局中增加一个button和一个progress
<Button android:id="@+id/webview_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击加载"/>
<ProgressBar
android:id="@+id/webview_progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:max="100"
android:progress="0" />```
我们在代码中自定义类
private class CustomChromeClient extends WebChromeClient{
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
mProgressBar.setProgress(newProgress);
if (newProgress == mProgressBar.getMax()) {
mProgressBar.setVisibility(View.GONE);
} else {
mProgressBar.setVisibility(View.VISIBLE);
}
}
}同时
mWebView.setWebChromeClient(new CustomChromeClient());```
点击界面的按钮,我们可以看到在按钮下方的进度条,会有一个进度。这个进度条的样式是系统默认的样式。但是我们发现,我们的进度条在加载到100的时候,又重头加载了一次。我们可以通过在onProgressChanged打log来跟踪,进度的变化情况。因为我们访问的是http://www.baidu.com. 这个会自动重定向到一个新的url。
我们是怎么发现它定向到一个新的地址的呢?我们定义了一个类
private class CustomWebViewClient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view,url);
}
}```
并且添加
```mWebView.setWebChromeClient(new CustomChromeClient());```
运行后,在类里面打日志,会发现我们的百度的地址做了重定向。我再次用chrome浏览器访问百度的地址,没有发现进度条出现的状况。在chrome里显示新闻以及广告,在我们的app了没有。我怀疑是网页内js和css的问题。所以设置了
mWebView.getSettings().setJavaScriptEnabled(true);//支持js```
这样再次运行的时候就不会出现进度条结束后又重新走的情况,我们观察下shouldOverrideUrlLoading里方法的日志。没有重定向。而且显示新闻和广告跟chrome浏览器里显示的一样了。
3.了解一下WebViewClient
点到这个类里可以看到有好多方法。
1.onPageStarted和onPageFinished
根据字面意思就是在加载页面的开始和结束的时候调用的方法。
如果我们要显示一个不用时时更新进度的进度条,就可以放在这两个位置完成进度条的隐藏和现实。
2.public boolean shouldOverrideUrlLoading(WebView view, String url) 在onpagestarted方法后 会回调这个这个方法
在加载url时我们会首先调用这个方法,拦截要访问的url。这个方法的默认返回值是false,就是默认加载url。如果返回true为不加载。
如下
mWebView.setWebViewClient(new WebViewClient());
如果我们不setWebViewClient 那么网页就会在系统浏览器中打开。
这个方法能做什么呢?
-
在webview中打开应用
//在方法中添加,跳转到应用市场。 url="market://details?id=com.instagram.android"; //打开应用市场 if(url.startsWith("market:")){ Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); if (intent.resolveActivity(getPackageManager()) != null) { //可以接收 startActivity(intent); } return true; } ```
地址替换
在方法里判断 如果为某一网址,则替换为其他网址。
如果想在webview中打开,不跳转。
if(url.startsWith("market://")){
String tmpUrl=url.substring(9);
url="https://play.google.com/store/apps/"+tmpUrl;
}```
当然我们还可以打开其他应用。应用的地址通常可能是。pinterest://feed/home?link_click_id=292551922683456291
跟处理market的方法一致。
pinterest://feed/home?类似这样的url是可以自定义的(设置启动activity的data方法里的schema port等参数)。相关帮助可以搜索“在浏览器中打开应用”。
#####3.public void onLoadResource(WebView view, String url) 在每次在加载资源前会调用该方法.
资源有.js .css 图片类型 链接等
private final Pattern imageUrlPattern = Pattern.compile("(.)+\(jpg|gif|png|bmp|jpeg){1}", Pattern.CASE_INSENSITIVE);```
Matcher m = imageUrlPattern.matcher(url);
if (m.find()) {
Log.i(WEBVIEWLOG,"保存这张图片");
}```
上面的代码用来获取后缀符合要求的图片资源。有些图片资源的url并没有.jpg这样的后缀,那我们需要URLConnect重新去访问这个资源url,并获取contentType 根据这个值来确定是否为图片。
#####4 public WebResourceResponse shouldInterceptRequest(WebView view,String url)
跟上面介绍的类似,也是在加载资源的时候会调用此方法,这个的调用在onLoadResource方法之前。
此方法默认是返回null,会加载当前页面的资源。这个方法是在非UI线程里执行的,所以如果要更新UI需要使用handler。
我们可以用这个方法来做什么?
可以在返回WebResourceResponse结果的时候替换为我们期待的结果,例如,我们替换网页中的图片。或者插入我们本地网页。
//将网页替换为本地图片
@Override
public WebResourceResponse shouldInterceptRequest(WebView view,String url) {
WebResourceResponse response = null;
try {
InputStream input = getAssets().open("Jellyfish.jpg");
response = new WebResourceResponse("image/png", "UTF-8", input);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}```
5.WebViewClient的其他方法
- onFormResubmission 是否重发post请求,默认为不重发
- doUpdateVisitedHistory 更新访问历史
- onReceivedLoginRequest 通知主程序执行了自动登录请求
- onReceivedSslError 接收HTTPS页面的错误
- onReceivedError 接收HTTP页面的错误
参考文章http://blog.csdn.net/harvic880925/article/details/51523983