WebView(网络视图)能加载显示网页,可以将其视为一个浏览器。它使用了WebKit渲染引擎加载显示网页,实现WebView有以下两种不同的方法:
第一种方法的步骤:
1.在要Activity中实例化WebView组件:WebView webView = new WebView(this);
2.调用WebView的loadUrl()方法,设置WevView要显示的网页:
互联网用:webView.loadUrl("http://www.google.com");
本地文件用:webView.loadUrl("file:///android_asset/XX.html"); 本地文件存放在:assets 文件中
3.调用Activity的setContentView( )方法来显示网页视图
4.用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面
5.需要在AndroidManifest.xml文件中添加权限,否则会出现Web page not available错误。
<uses-permission android:name="android.permission.INTERNET" />
下面是具体例子:
MainActivity.java
package com.android.webview.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
public class MainActivity extends Activity {
private WebView webview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//实例化WebView对象
webview = new WebView(this);
//设置WebView属性,能够执行Javascript脚本
webview.getSettings().setJavaScriptEnabled(true);
//加载需要显示的网页
webview.loadUrl("http://www.51cto.com/");
//设置Web视图
setContentView(webview);
}
@Override
//设置回退
//覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
webview.goBack(); //goBack()表示返回WebView的上一页面
return true;
}
return false;
}
在AndroidManifest.xml文件中的17行添加权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.webview.activity"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
效果图:
第二种方法的步骤:
1、在布局文件中声明WebView
2、在Activity中实例化WebView
3、调用WebView的loadUrl( )方法,设置WevView要显示的网页
4、为了让WebView能够响应超链接功能,调用setWebViewClient( )方法,设置 WebView视图
5、用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面
6、需要在AndroidManifest.xml文件中添加权限,否则出现Web page not available错误。
<uses-permission android:name="android.permission.INTERNET"/>
下面是具体的例子:
MainActivity.java
package com.android.webview.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
private WebView webview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webview = (WebView) findViewById(R.id.webview);
//设置WebView属性,能够执行Javascript脚本
webview.getSettings().setJavaScriptEnabled(true);
//加载需要显示的网页
webview.loadUrl("http://www.51cto.com/");
//设置Web视图
webview.setWebViewClient(new HelloWebViewClient ());
}
@Override
//设置回退
//覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
webview.goBack(); //goBack()表示返回WebView的上一页面
return true;
}
return false;
}
//Web视图
private class HelloWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
在AndroidManifest.xml文件中的17行添加权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.webview.activity"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件
WebView在开发过程中应该注意几点:
1.AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Webpage not available错误。
2.如果访问的页面中有Javascript,则webview必须设置支持Javascript。
WebSettings webSetting = webview.getSettings();
webSetting.setJavaScriptEnabled(true);
3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖webview的WebViewClient对象。
1 mWebView.setWebViewClient(new WebViewClient(){
2 publicboolean shouldOverrideUrlLoading(WebView view, String url) {
3 view.loadUrl(url);
4 returntrue;
5 }
6 });
4.如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。
7 publicboolean onKeyDown(int
keyCode, KeyEventevent) {
8 if((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
9 mWebView.goBack();
10 returntrue;
11 }
12 returnsuper.onKeyDown(keyCode,event);
13 }
5.如果webView中需要用户手动输入用户名、密码或其他,则webview必须设置支持获取手势焦点。
webview.requestFocusFromTouch();
6.WebView 加载界面主要调用三个方法:LoadUrl、LoadData、LoadDataWithBaseURL.
1、LoadUrl 直接加载网页、图片并显示.(本地或是网络上的网页、图片、gif)
2、LoadData 显示文字与图片内容(模拟器1.5、1.6)
3、LoadDataWithBase 显示文字与图片内容(支持多个模拟器版本)
WebSettings的常用方法介绍
14
setJavaScriptEnabled(true);
//支持js脚步
15 setPluginsEnabled(true);
//支持插件
16 setUseWideViewPort(false);
//将图片调整到适合webview的大小
17 setSupportZoom(true);
//支持缩放
18 setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
//支持内容从新布局
19 supportMultipleWindows();
//多窗口
20 setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//关闭webview中缓存
21 setAllowFileAccess(true);
//设置可以访问文件
22 setNeedInitialFocus(true);
//当webview调用requestFocus时为webview设置节点
webSettings.setBuiltInZoomControls(true);
//设置支持缩放
23 setJavaScriptCanOpenWindowsAutomatically(true);
//支持通过JS打开新窗口
24 setLoadsImagesAutomatically(true);
//支持自动加载图片
WebViewClient的方法全解
25 doUpdateVisitedHistory(WebViewview,Stringurl,
boolean isReload)
(更新历史记录)
26 onFormResubmission(WebViewview,MessagedontResend,Messageresend)
(应用程序重新请求网页数据)
27 onLoadResource(WebViewview,Stringurl)
在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
28 onPageStarted(WebViewview,Stringurl,Bitmapfavicon)
这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告
诉用户程序在等待网络响应。
29 onPageFinished(WebViewview,Stringurl)
在页面加载结束时调用。同样道理,我们知道一个页面载入完成,于是我们可以关
闭loading 条,切换程序动作。
30 onReceivedError(WebViewview,
int errorCode, Stringdescription,StringfailingUrl)
(报告错误信息)
31 onReceivedHttpAuthRequest(WebViewview,HttpAuthHandlerhandler,Stringhost,
Stringrealm)(获取返回信息授权请求)
32 onReceivedSslError(WebViewview,SslErrorHandlerhandler,SslErrorerror)
重写此方法可以让webview处理https请求。
33 onScaleChanged(WebViewview,
float oldScale, float newScale)
(WebView发生改变时调用)
34 onUnhandledKeyEvent(WebViewview,KeyEventevent)
(Key事件未被加载时调用)
35 shouldOverrideKeyEvent(WebViewview,KeyEventevent)
重写此方法才能够处理在浏览器中的按键事件。
36 shouldOverrideUrlLoading(WebViewview,Stringurl)
在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。
原来是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下载。具体操作如下:
1、设置WebView的DownloadListener:
webView.setDownloadListener(new MyWebViewDownLoadListener());
2、实现MyWebViewDownLoadListener这个类,具体可以如下这样:
- private class MyWebViewDownLoadListener implements DownloadListener {
- @Override
- public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
- long contentLength) {
- Uri uri = Uri.parse(url);
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- startActivity(intent);
- }
- }
这只是调用系统中已经内置的浏览器进行下载,还没有WebView本身进行的文件下载,不过,这也基本上满足我们的应用场景了。
1、添加上网权限:<uses-permission android:name="android.permission.INTERNET" />
2、设置webview
1 WebView webView; 2 WebSettings ws; 3 4 5 ws = webView.getSettings(); 6 ws.setAppCacheEnabled(true);// 设置启动缓存 7 ws.setAppCacheMaxSize(1024 * 10);// 设置最大缓存 8 ws.setSupportZoom(true);// 设置成拖动放大缩小 9 ws.setBuiltInZoomControls(true); 10 ws.setCacheMode(WebSettings.LOAD_NO_CACHE);// 设置缓存模式 11 // 设置支持Javascript 12 webView.getSettings().setJavaScriptEnabled(true); 13 webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); 14 15 // 缓存,离线应用 16 webView.getSettings().setAppCacheEnabled(true); 17 webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); 18 webView.getSettings().setAppCacheMaxSize(1024 * 1024 * 8);
3、获取网页对话框
webView.setWebChromeClient(new WebChromeClient() { @Override public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { // TODO Auto-generated method stub // 构建一个Builder来显示网页中的对话框 Builder builder = new Builder(context); builder.setTitle("警告"); builder.setMessage(message); builder.setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // 点击确定按钮之后,继续执行网页中的操作 result.confirm(); } }); builder.setCancelable(false); builder.create(); builder.show(); return true; } @Override public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { // TODO Auto-generated method stub Builder builder = new Builder(context); builder.setTitle("confirm"); builder.setMessage(message); builder.setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { result.confirm(); } }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { result.cancel(); } }); builder.setCancelable(false); builder.create(); builder.show(); return true; } @Override public void onProgressChanged(WebView view, int newProgress) {// 加载进度 // TODO Auto-generated method stub super.onProgressChanged(view, newProgress); } });
4、如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。
给WebView添加一个事件监听对象(WebViewClient)
5、webview取得焦点
webView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub webView.requestFocus(); return false; } });
6、提示加载对话框
pd=ProgressDialog.show(context, "请稍后", "正在加载中...");
当网页加载完成后,调用pd.dismiss();
Settings是WebView提供给上层App的一个配置Webview的接口,每个WebView都有一个WebSettings,要控制WebView的行为,只能通过WebView.getSettings()获取WebSettings对象的引用,然后再改变它的属性。
Browser有一个BrowserSettings用来管理所有的配置信息,它是一个单键(Singleton)。BrowserSettings是直接管理WebSettings的,而UI部分则是由BrowserPreferencePage和Fragment来完成。BrowserSettings实现了OnSharedPreferenceChangedListener,当某个配置项发生变化时,BrowserSettings的接口onPreferencesChanged就会被回调到,然后BrowserSettings就会把配置通过WebSettings应用到WebView中,所以这些Settings都是及时生效的。
一共有三类Settings:共享Settings,静态Settings和动态Settings。静态就是不会在Browser运行时发生变化的,也就是说在Browser的Settings中无法改变的一些配置,这些跟应用程序内部关联较多,比如应用程序的数据存放地点等,而与用户层关系不多;共享Settings是独立于WebView的,也就是说它被系统内所有WebView共享的一些配置,比如Cookie,它不需要为每个WebView单独配置。动态Settings就是用于动态配置WebView的,比如字体,缩放,是否加载图片,是否启用JavaScript等等。
初始化
因为Browser可以有多个窗口,每一个窗口都会有一个WebView,也就是说Browser会管理多个WebView,所以BrowserSettings也要管理多个WebSettings,因为每一个配置的改变都要应用到所有的WebView中。为了能让BrowserSettings能够管理多个WebSettings,它必须持有对这些WebSettings的引用。Browser在创建WebView的时候会把WebView的配置WebSettings通过接口放到BrowserSettings中,BrowserSettings中有一个列表,用于持有对WebSettings的引用。具体的BrowserWebViewFactory中的initWebViewSettings()方法会在每次创建WebView后调用,它把WebView的WebSettings取出,做些必要的初始化,然后放到BrowserSettings中,BrowserSettings.startManagingSettings()会加载SharedPreference文件中的信息对此WebSettings进行初始化,然后放到mManagedSettings列表中。
配置变更
用户进入Settings界面,进行配置的更改,每当有配置发生变化BrowserSettings.onSharedPreferencesChanged()会被回调到,它就会做syncManagedSettings()的动作,把共享设置同步到底层去(也即把设置同步到Cookiemanager中),再遍历列表mManagedSettings,把mPref中的信息全部同步到每个WebSettings中,这样所有的WebView都会实时的响应配置变更。
设置的界面和BrowserSettings没有直接的关联,界面是通过PreferenceActivity和Fragment把各种Settings呈现给用户,而BrowserSettings是把配置信息同步给WebView也就是让配置生效。它们之间的信息桥梁是SharedPreference,也就是说PreferenceActivity和Fragment从用户处接收配置信息,然后放到SharedPreference中,BrowserSettin
Android WebView缓存
在项目中经常会使用到WebView控件,当加载html页面时,会在/data/data/应用package目录下生成database与cache两个文件夹如下图如示:
请求的url记录是保存在webviewCache.db,而url的内容是保存在webviewCache文件夹下.
为了便于理解,接下来模拟一个案例,定义一个html文件,在里面显示一张图片,用WebView加载出来,然后再试着从缓存里把这张图片读取出来并显示。
第一步:新建一个Android工程命名为WebViewCache.目录结构如下:
第二步:在assets目录下新建一个html文件,命名为index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>WebViewCacheDemo</title><meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<