Android WebView API 中文参考手册及使用方法
基本方法
getUrl
public String getUrl(); //获取当前网页的url
需要注意,通过这个方法获取的url并不一定就是当前WebView正在加载的url。因为可能在调用这个方法的时候,url对应的网页还未加载完毕,那么获得的就是旧的url。
getOriginalUrl
public String getOriginalUrl(); //获得当前网页的原始url
之所以会有原始url的概念,是因为某些网页会执行重定向操作,那么通过这个方法获取的就是重定向之前的url。此外,这个方法和getUrl类似,如果当前网页还未加载完毕,那么获得的就是旧的原始url。
getTitle
public String getTitle(); //获得当前网页的标题
getFavicon
public Bitmap getFavicon(); //获得当前网页的图标
getProgress
public int getProgress(); //获得当前网页的加载进度(0-100)
setNetworkAvailable
//设置当前网络是否可用
//networkUp:当前网络是否可用
public void setNetworkAvailable(boolean networkUp);
通过这个方法可以设置当前网络是否可用,借此触发HTML5和JS的online/offline模式,但是并不会对WebView的网络访问产生实质性影响。
setInitialScale
//设置WebView的缩放等级
//scaleInPercent:缩放等级
public void setInitialScale(int scaleInPercent);
scaleInPercent是缩放等级,如果传入50,代表缩小1倍;如果传入200,代表放大1倍。注意,如果传入0,代表启用默认模式,缩放等级取决于setUseWideViewPort和setLoadWithOverviewMode两个方法的传入值。
网页加载
loadUrl
//url:本次加载的地址
public void loadUrl(String url);
//携带请求头信息加载url
//additionalHttpHeaders:保存请求头信息
public void loadUrl(String url, Map<String, String> additionalHttpHeaders);
loadUrl用于加载指定url,这个url可以是远程网页的链接,也可以是本地的资源链接,大致有以下几种格式:
- 加载assets下的资源:file:///android_asset/
- 加载res下的资源:file:///android_res/
- 加载raw下的资源:file:///android_res/raw/
- 加载sdcard下的资源:file:/sdcard/或file:///sdcard/或content://com.android.htmlfileprovider/sdcard/
loadData
//以字符串形式加载html片段
//data:html片段
//mimeType:数据类型,如"text/html"
//encoding:数据编码,有两种可选值("base64"和其他任何值),分别代表base64编码和URL编码
public void loadData(String data, String mimeType, String encoding);
为mimeType传入null和传入”text/html”意义相同。为encoding传入除”base64”外的任何值,都相当于是指定数据编码为URL编码,一般传入null即可。
需要注意,如果data中包含中文,结果将显示为乱码,需要为mimeType传入"text/html;charset=UTF-8"
。
此外,data中的’#’,’%’,’\’,’?’应该分别被替换为%23,%25,%27,%3f
loadDataWithBaseURL
//以字符串形式加载html片段
//baseUrl:基础url,传入null相当于传入了"about:blank"
//data:html片段
//mimeType:数据类型,如"text/html"
//encoding:数据编码,有两种可选值("base64"和其他任何值),分别代表base64编码和URL编码
//historyUrl:历史url
public void loadDataWithBaseURL(String baseUrl, String data,String mimeType, String encoding, String historyUrl);
loadUrlWithBaseURL方法和loadData类似,主要是用于解决Javascript的同源限制问题。实际上,如果为baseUrl和history传入null,那么loadUrlWithBaseURL和loadData方法作用相同,并且加载中文数据不会出现乱码的问题。
postUrl
//以post请求的形式访问url
//postData:本次post请求携带的数据,必须是application/x-www-form-urlencoded编码
public void postUrl(String url, byte[] postData);
如果传入的url不是一个远程网页地址,那么最终将通过loadUrl方法加载这个url,同时postData参数会被忽略。
刷新页面和停止加载
public void reload(); //刷新页面(当前页面的所有资源都会重新加载)
public void stopLoading(); //停止加载
JS相关
addJavascriptInterface
//为JS添加Java映射对象
//object:Java映射对象,包含Javascript需要调用的方法
//name:object在Javascript中的映射名称
public void addJavascriptInterface(Object object, String name);
这个方法需要在WebSettings调用setJavaScriptEnabled(true)
启用JS功能后才有意义。用于为JS添加Java映射对象,JS可以借助这个映射对象调用Java代码。
removeJavascriptInterface
//移除JS中的Java映射对象
//name:Java对象的映射名称
public void removeJavascriptInterface(String name);
evaluateJavascript
//用于Android异步执行JS代码 [Android 4.4(API 19)及以上可用]
//script:需要执行的JS代码
//resultCallback:用于提供JS方法的返回值
public void evaluateJavascript(String script, ValueCallback<String> resultCallback);
这种方式使用起来很简单,只要按照正确的格式传入一个字符串即可。格式:(javascript:JS方法名)。需要注意,被调用的方法需要已在当前页面定义或者已经引入当前页面(JS系统方法也可以)
需要注意,这个方法只能在UI线程中调用,最终resultCallback的回调方法也会在UI线程中执行。
导航功能
基础操作
public boolean canGoBack(); //判断是否可以后退
public void goBack(); //后退
public boolean canGoForward(); //判断是否可以前进
public void goForward(); //前进
指定后退/前进步数
//判断是否可以后退/前进相应步数
public boolean canGoBackOrForward(int steps);
//后退/前进相应步数
public void goBackOrForward(int steps);
steps大于0表示前进(forward),小于0表示后退(back)。
网页查找
setFindListener
//为WebView注册查找监听器
//listener:查找监听器。会在每次执行findAll、findNext、findAllAsync方法后触发onFindResultReceived方法。
public void setFindListener(FindListener listener);
findAll
//在当前网页中寻找所有的匹配内容并高亮显示它们 [Android 4.1(API 16)及以上已弃用]
//find:需要查找的目标内容
//return:返回已查找到的目标数目
public int findAll(String find);
这个方法会阻塞UI线程,在Android 4.1及以上推荐使用findAllAsync方法代替。
findAllAsync
//在当前网页中异步寻找所有匹配内容并高亮显示它们 [Android 4.1(API 16)及以上可用]
//find:需要查找的目标内容
public void findAllAsync(String find);
这个方法异步执行,不会阻塞UI线程。
findNext
//跳转到下一个高亮显示的匹配内容
//forward:跳转的方向。true为向下查找,false为向上查找。
public void findNext(boolean forward);
这个方法需要在findAllAsync方法执行后才能调用,否则不会生效。
clearMatches
//清除当前高亮显示的所有匹配内容
public void clearMatches();
离线保存网页
//将当前网页保存下来(一般以.mht文件的形式)
//filename:离线网页的文件名。
public void saveWebArchive(String filename);
//将当前网页保存下来(一般以.mht文件的形式)
//basename:离线网页的基础文件名。
//autoname:是否自动生成文件名。如果autoname为false,basename就必须是一个完整的合法文件名;否则,basename将会是一个文件夹,离线网页的文件名会根据url自动生成。
//callback:回调器。
public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback);
callback会在离线网页保存完成后回调自己的onReceiveValue方法。如果保存成功,onReceiveValue的参数将会是离线网页的文件名;如果保存失败,onReceiveValue的参数将会是null。
翻页
//向上翻页(默认滚动半屏的距离)
//top:如果为true将直接跳转到页面顶部
//return:如果页面发生滚动将返回true,否则返回false
public boolean pageUp(boolean top);
//向下翻页(默认滚动半屏的距离)
//bottom:如果为true将直接跳转到页面底部
//return:如果页面发生滚动将返回true,否则返回false
public boolean pageDown(boolean bottom);
缩放
//放大页面
//return:如果页面成功放大,将返回true,否则返回false
public boolean zoomIn();
//缩小页面
//return:如果页面成功缩小,将返回true,否则返回false
public boolean zoomOut();
//按照指定比例缩放页面
//缩放比例(0.01-100)
public void zoomBy(float zoomFactor);
清除数据
clearCache
//清除缓存
//includeDiskFiles:传入false仅清除内存缓存,传入true将同时清除内存和磁盘缓存
public void clearCache(boolean includeDiskFiles);
clearHistory
public void clearHistory(); //清除浏览历史
clearFormData
public void clearFormData(); //清除表单数据
注意,clearFormData仅仅清除表单的自动填充数据,并不会影响已经存储到本地的表单数据。
clearSslPreferences
public void clearSslPreferences(); //清除SSL偏好设置
WebView状态
针对当前WebView
public void onPause(); //尽最大努力暂停WebView当前可被安全暂停的行为(如动画、定位),但并不暂停Javascript
public void onResume(); //恢复WebView被onPause暂停的行为
针对全局WebView
public void pauseTimers(); //暂停WebView的所有行为
public void resumeTimers(); //恢复WebView被pauseTimers暂停的行为
注意,pauseTimers是一个全局方法,针对的是所有App的WebView。恰当地使用这一方法可以降低CPU功耗。
销毁WebView
public void destroy(); //销毁WebView
注意,需要先将WebView从它所在的ViewGroup中移除后,这个方法才能生效。
页面高度
public int getContentHeight(); //获得网页内容高度
其他
documentHasImages
//查询当前网页,判断是否存在图片
//response:包含本次查询的结果。如果当前网页中包含图片,response.arg1值为1,否则为0。
public void documentHasImages(Message response);
注意,作为参数的Message必须有一个与之绑定的Handler对象(使用Message.obtain()
方法)。在完成对网页的查询后,response会被发送到这个Handler的handleMessage方法中。下面提供一个简单的例子:
public static class TestHandler extends Handler{
@Override
public void handleMessage(Message msg) {
if(msg.arg1==1){
Log.i(TAG,"当前网页中存在图片");
}else{
Log.i(TAG,"当前网页中不存在图片");
}
}
};
//查询网页中是否有图片
Message msg=Message.obtain(new TestHandler());
webView.documentHasImages(msg);
requestImageRef
//获取网页中最近触摸过的图像的url
//msg:包含本次查询的结果。msg.getData()包含了图像的url,可以将"url"作为key进行获取。(形如:msg.getData().getString("url"))
public void requestImageRef(Message msg);
注意,和documentHasImage类似,作为参数的Message必须有一个与之绑定的Handler对象。此外,如果并未触摸过任何图片,获取到的url会是null。
setWebContentsDebuggingEnabled
//设置网页内容(HTML、CSS、JS)是否开启调试模式 [Android 4.4(API 19)及以上可用]
//enabled:是否开启调试模式。默认为false。
public static void setWebContentsDebuggingEnabled(boolean enabled);
2.WebSettings
缓存设置
setAppCacheEnabled
//设置是否开启应用缓存
//flag:是否开启应用缓存。默认为false。
public abstract void setAppCacheEnabled(boolean flag);
注意,如果要开启应用缓存,就必须调用setAppCachePath方法设置缓存路径。
setAppCachePath
//设置应用缓存路径
//appCachePath:应用缓存路径。
public abstract void setAppCachePath(String appCachePath);
注意,这个方法只能调用一次,后续调用会被忽略。
setCacheMode
//设置浏览器的缓存模式
//mode:缓存模式。可选值:LOAD_DEFAULT、LOAD_NO_CACHE、LOAD_CACHE_ONLY、LOAD_CACHE_ELSE_NETWORK。
public abstract void setCacheMode(int mode);
四种缓存模式的区别如下:
- LOAD_DEFAULT:默认值。当存在缓存且未过期时加载缓存数据,否则通过网络加载数据。
- LOAD_NO_CACHE:不使用缓存。仅通过网络加载数据。
- LOAD_CACHE_ONLY:只使用缓存。仅加载缓存数据,不通过网络加载数据。
- LOAD_CACHE_ELSE_NETWORK:只要存在缓存,不管是够过期都加载缓存数据,否则通过网络极加载数据。
setDatabaseEnabled
//设置database storage API是否可用
//flag:是否可用。默认为false。
public abstract void setDatabaseEnabled(boolean flag);
setDatabasePath
//设置database storage API的数据存储路径 [Android 4.4(API 19)及以上已弃用]
//databasePath:数据存储路径。
public abstract void setDatabasePath(String databasePath);
这个方法只能调用一次,后续调用会被忽略。
setDomStorageEnabled
//设置DOM storage API是否可用
//flag:是否可用。默认为false。
public abstract void setDomStorageEnabled(boolean flag);
定位
//设置定位功能是否可用
//flag:是否启用。默认为true
public abstract void setGeolocationEnabled(boolean flag);
需要注意,这个方法只是允许网页执行定位操作,但是最终定位操作的实现还是会委托给Android应用处理。因此,为了保证定位功能正常执行,需要满足以下两点:
- Android应用需要获取定位权限。需要在AndroidManifest文件中声明android.Manifest.permission.ACCESS_COARSE_LOCATION和android.Manifest.permission.ACCESS_FINE_LOCATION两个权限。
- 需要为WebView设置WebChromeClient,并重写WebChromeClient的onGeolocationPermissionsShowPrompt方法。这个方法会在网页中的Javascript代码执行定位操作时触发。需要注意,Android6.0及以上引入了运行时权限的概念。定位属于危险权限,需要在使用时手动获取。因此可以在这个回调方法中弹出一个请求定位的提示对话框(AlertDialog),在用户选择确定后获得相应权限。
如果不了解运行时权限的概念,可以参考这篇博客:
自动保存
setSaveFormData
//设置是否保存表单数据(用于自动填充) [Android 4.3(API 18)及以上已弃用]
//save:是否保存。默认为true。
public abstract void setSaveFormData(boolean save);
setSavePassword
//设置是否保存密码
//save:是否保存。默认为true。
public abstract void setSavePassword(boolean save);
在Android 4.3(API 18)以前,如果启用保存密码功能,用户在WebView加载的网页中输入密码后,系统会弹出对话框询问用户是否需要保存密码。如果用户选择保存,那么密码将会以明文的形式保存在本地,显然这是一个巨大的安全隐患。因此,在Android 4.3及以上的版本,setSavePassword方法已经被弃用,WebView也不会默认保存密码.
屏幕自适应
setUseWideViewPort
//设置是否支持HTML中的<viewport>元标签
//use:是否支持。
public abstract void setUseWideViewPort(boolean use);
如果use为false,WebView将启用wide viewport模式,网页宽度将会是设置在CSS中的实际尺寸;否则,网页宽度将受到HTML中<viewport>
标签的控制,根据设备的不同将会有所调整。
注意,即使启用了这个功能,如果HTML中并没有<viewport>
标签或者<viewport>
标签并未正确设置,那么WebView依旧会使用wide viewport模式。
setLoadWithOverviewMode
//设置网页是否以overview模式加载
//overview:是否使用overview模式。默认为false。
public abstract void setLoadWithOverviewMode(boolean overview);
如果overview为true,WebView将会缩小网页内容以便适配设备屏幕宽度,这在网页内容大于屏幕宽度的时候非常有用。通常情况,这个方法会配合setUseWideViewPort
方法一起使用(两个方法都传入true),以达到网页内容自适应屏幕的目的。
JS设置
setJavaScriptEnabled
//设置是否启用对Javascript的支持
//flag:是否支持Javascript。默认为false。
public abstract void setJavaScriptEnabled(boolean flag);
需要注意,通过这种方式支持Javascript在Android 4.2(API 17)以下存在严重的安全隐患。
setJavaScriptCanOpenWindowsAutomatically
//设置JS是否可以自动打开窗口
//flag:是否可以。默认为false。
public abstract void setJavaScriptCanOpenWindowsAutomatically(boolean flag);
这个方法主要影响Javascript的window.open()
方法。
支持插件
//设置WebView是否支持插件 [Android 4.3(API 18)及以上已弃用]
//state:对插件的支持模式。可选值:PluginState.ON,PluginState.ON_DEMAND,PluginState.OFF。
public abstract void setPluginState(PluginState state);
三种支持模式的区别:
- OFF:默认值。不支持插件。
- ON:支持插件。
- ON_DEMAND:在插件所在的位置显示一个图像占位符。如果用户点击占位符,就启用插件,否则禁用插件。
资源访问
setAllowContentAccess
//设置是否允许WebView通过ContentProvider加载资源(url格式形如content://)
//allow:是否允许。默认为true。
public abstract void setAllowContentAccess(boolean allow);
setAllowFileAccess
//设置是否允许WebView访问本地文件系统
//allow:是否允许。默认为true。
public abstract void setAllowFileAccess(boolean allow);
注意,这个方法并不影响对assets和resources资源的加载。它们的url格式分别为:file:///android_asset、file:///android_res
。
setAllowFileAccessFromFileURLs
//设置是否允许通过file协议(file:///)加载的Javascript访问本地文件系统
//flag:是否允许。Android 4.1(API 16)以下默认为true,Android 4.1及以上默认为false。
public abstract void setAllowFileAccessFromFileURLs(boolean flag);
setAllowUniversalAccessFromFileURLs
//设置是否允许通过file协议(file:///)加载的Javascript访问任何来源的数据
//flag:是否允许。Android 4.1(API 16)以下默认为true,Android 4.1及以上默认为false。
public abstract void setAllowUniversalAccessFromFileURLs(boolean flag);
所谓任意来源,包括本地文件系统、其他file协议。
资源加载
setLoadImageAutomatically
//设置WebView是否应该自动加载图像资源
//flag:是否允许。默认为true。
public abstract void setLoadsImagesAutomatically(boolean flag);
注意,这个方法会影响所有的图像资源的加载,包括嵌入HTML页面的本地图像资源。
注意,如果调用这个方法将flag的值从false改变为true,网页中原本被阻塞的图像资源将自动加载。
setBlockNetworkLoads
//设置是否禁止WebView加载网络资源
//flag:是否禁止。
public abstract void setBlockNetworkLoads(boolean flag);
如果当前应用有android.permission.INTERNET
权限,flag默认为false,否则默认为true。
注意,即使将flag的值从true改变为false,网页中已经被阻塞的网络资源也不会自动加载,除非再调用WebView的reload
方法刷新页面。
setBlockNetworkImage
//设置是否禁止WebView加载网络图像资源
//flag:是否禁止。默认为false。
public abstract void setBlockNetworkImage(boolean flag);
网络图像资源包括使用http和https协议加载的资源。注意,如果已经通过setLoadsImagesAutomatically(false)
禁止自动加载图像资源,或者已经调用setBlockNetworkLoads(true)
禁止加载网络资源,这个方法将没有任何作用。
注意,如果调用这个方法将flag的值从true改变为false,网页中原本被阻塞的网络图像资源将自动加载。
缩放设置
setSupportZoom
//设置WebView是否支持缩放功能
//support:是否支持。默认为true。
public abstract void setSupportZoom(boolean support);
注意,这个方法并不影响WebView的zoomIn
和zoomOut
方法。
setBuiltInZoomControls
//设置是否使用WebView内置的缩放功能(允许通过手势控制缩放)
//enabled:是否使用。默认为false。
public abstract void setBuiltInZoomControls(boolean enabled);
setDisplayZoomControls
//设置是否显示WebView内置的虚拟缩放按钮
//enabled:是否显示。默认为true。
public abstract void setDisplayZoomControls(boolean enabled);
编码
//设置默认文本编码
//encoding:编码名称。默认为"UTF-8"。
public abstract void setDefaultTextEncodingName(String encoding);
字体
字体大小
//设置默认字体大小
//size:字体大小(1-72)。默认为16。
public abstract void setDefaultFontSize(int size);
//设置默认固定字体大小
//size:字体大小(1-72)。默认为16。
public abstract void setDefaultFixedFontSize(int size);
//设置最小字体大小
//size:字体大小(1-72)。默认为8。
public abstract void setMinimumFontSize(int size);
//设置最小逻辑字体大小
//size:字体大小(1-72)。默认为8。
public abstract void setMinimumLogicalFontSize(int size);
字体族
//设置standard字体族
//font:字体族名称。默认为"sans-serif"。
public abstract void setStandardFontFamily(String font);
//设置cursive字体族
//font:字体族名称。默认为"cursive"。
public abstract void setCursiveFontFamily(String font);
//设置fantasy字体族
//font:字体族名称。默认为"fantasy"。
public abstract void setFantasyFontFamily(String font);
//设置fixed字体族
//font:字体族名称。默认为"monospace"。
public abstract void setFixedFontFamily(String font);
//设置serif字体族
//font:字体族名称。默认为"sans-serif"。
public abstract void setSerifFontFamily(String font);
//设置sans-serif字体族
//font:字体族名称。默认为"sans-serif"。
public abstract void setSansSerifFontFamily(String font);
字体族是指一组具有统一外观的字体,它们具有一些共同的特点。
其他
setSupportMultipleWindows
//设置WebView是否支持多窗口
//support:是否支持。默认为false。
public abstract void setSupportMultipleWindows(boolean support);
注意,如果通过这个方法支持多窗口模式,就必须实现WebChromeClient
的onCreateWindow
方法。
setNeedInitialFocus
//设置是否需要在WebView调用requestFocus方法时为网页内的一个节点(标签)赋予焦点
//flag:是否需要。默认为true。
public abstract void setNeedInitialFocus(boolean flag);
setMixedContentMode
//设置混合内容模式(http、https)
//mode:混合内容模式。可选值:MIXED_CONTENT_NEVER_ALLOW、MIXED_CONTENT_ALWAYS_ALLOW、MIXED_CONTENT_COMPATIBILITY_MODE
public abstract void setMixedContentMode(int mode);
所谓混合内容,是指在https请求的网页中使用http协议请求资源。由于这一过程存在不安全的因素,因此需要为WebView设置相应的混合内容模式,三种可选值的区别如下:
- MIXED_CONTENT_NEVER_ALLOW:不允许混合使用https和http。
- MIXED_CONTENT_ALWAYS_ALLOW:始终允许混合使用https和http。
- MIXED_CONTENT_COMPATIBILITY_MODE:部分允许混合使用https和http。这个模式会尝试以安全的方式加载部分http资源,另一部分http资源则不会被加载。资源是否能被加载的判断依据可能会随着版本的不同而改变,因此需要根据实际情况决定是否采用这一模式。
在Android 5.0(API 21)以下mode默认为MIXED_CONTENT_ALWAYS_ALLOW,Android 5.0及以上mode默认为MIXED_CONTENT_NEVER_ALLOW。
setUserAgentString
//设置WebView的user-agent属性
//us:user-agent值。
public abstract void setUserAgentString(String ua);
user-agent指的是浏览器标识,如:User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
。
注意,如果ua为null或空字符串,那么WebView将会使用默认的user-agent值。
setLayoutAlgorithm
//设置WebView的布局算法
//l:布局算法。默认为LayoutAlgorithm.NARROW_COLUMNS。
public abstract void setLayoutAlgorithm(LayoutAlgorithm l);
注意,如果通过这个方法修改布局算法,将导致WebView重新布局。
3.WebViewClient
shouldOverrideUrlLoading
//拦截url跳转请求 [Android 5.0(API 21)已弃用]
//url:WebView即将加载的url
public boolean shouldOverrideUrlLoading(WebView view, String url);
//拦截url跳转请求 [Android 5.0(API 21)及以上可用]
//request:封装本次url请求的详细信息(包括url、请求方法、请求头)
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request);
以上两个方法都会在WebView加载新的url时触发。不同之处在于,第二个方法是在Android 5.0(API 21)之后才加入的。换句话说,Android 5.0以下系统会回调第一个方法,反之回调第二个方法。因此,为了兼容不同的系统版本,需要同时重写这两个方法。
可以看到,这两个方法都有一个boolean返回值。但是,无论返回true还是false,只要为WebView设置了WebViewClient,系统就不会再将url交给第三方的浏览器去处理了。
这两种返回值的真正区别是这样的:shouldOverrideUrlLoading返回false,代表将url交给当前WebView加载,也就是正常的加载状态;shouldOverrideUrlLoading返回true,代表开发者已经对url进行了处理,WebView就不会再对这个url进行加载了。使用true这个返回值的最大作用是屏蔽某些网址,可以借此实现黑名单机制。
shouldInterceptRequest
//拦截资源请求 [Android 5.0(API 21)已弃用]
//url:本次请求的url
public WebResourceResponse shouldInterceptRequest(WebView view,String url);
//拦截资源请求 [Android 5.0(API 21)及以上可用]
//request:封装本次请求的详细信息(包括url、请求方法、请求头)
public WebResourceResponse shouldInterceptRequest(WebView view,WebResourceRequest request);
以上两个方法都会在WebView发生资源请求的时候回调(使用loadUrl加载远程网页时也会触发这个方法),因此可以按照业务需求对资源进行替换。和shouldOverrideUrlLoading一样,第二个方法是在Android 5.0(API 21)之后才加入的。Android 5.0以下系统会回调第一个方法,反之回调第二个方法。因此,为了兼容不同的系统版本,需要同时重写这两个方法。
可以看到,shouldInterceptRequest的返回值是一个WebResourceResponse对象,在这个对象中封装了本次url响应的数据。因此,只要构造出一个包含目标数据的WebResourceResponse对象,并将其返回,就实现了资源的替换。在需要使用本地资源替换远程资源的场景中,这个回调方法非常有用。当然,如果直接返回null,WebView将会正常地加载url对应的资源。
需要注意,shouldInterceptRequest会在非UI线程中回调。因此,如果需要在这个方法中进行View操作,需要手动切换线程。
onPageStarted
//当前页面开始加载时触发
//url:当前网页的url
//favicon:当前网页的图标
public void onPageStarted(WebView view, String url, Bitmap favicon);
onPageFinished
//当前页面结束加载时触发
//url:当前网页的url
public void onPageFinished(WebView view, String url);
注意,即使onPageFinished方法已经回调,也并不代表当前页面中的所有资源都已经加载完毕,可能当前网页还在加载图片等比较耗时的资源。
onLoadResource
//资源加载时触发
//url:资源的url
public void onLoadResource(WebView view, String url);
onLoadResource将在WebView加载资源(如css、js、图片等)时回调。
onReceivedError
//网页发生错误时触发
//errorCode:错误码(定义在WebViewClient中,形式都是ERROR_*)
//description:对当前错误的描述
//failingUrl:发生错误的url
public void onReceivedError(WebView view, int errorCode,String description, String failingUrl);
//网页发生错误时触发
//request:封装本次请求的详细信息(包括url、请求方法、请求头)
//error:封装本次错误的详细信息(包括错误码和错误描述)
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error);
第一个方法会在当前页面内容加载发生错误时回调(不包括加载图片、css等出错的场景),第二个方法则会在当前页面的任何资源加载出错时回调(包括加载图片、css等出错的场景)。此外,在Android 6.0以下,系统会回调第一个方法,否则回调第二个方法。
onReceivedHttpError
//在加载资源发生http错误时触发
//request:封装本次请求的详细信息(包括url、请求方法、请求头)
//errorResponse:由服务器返回的错误反馈信息,可能为空。
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse);
注意,任何资源(如iframe、图像等)在加载出现http错误时都会触发这个方法,而不仅仅是主页面发生错误时才会触发。因此,建议在这个方法中只执行最少需要的操作。
onReceivedSslError
//在网页发生SSL错误时触发
//handler:错误处理器。可以执行handler.cancel()或者handler.proceed()。
//error:封装错误信息(SSL证书、url、错误码等)。
public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error);
在使用WebView加载https协议的网页或资源时,如果该网站的安全证书不被Android认可,就会出现SSL错误。如果执行handler.cancel(),将取消这次请求;如果执行handler.proceed(),WebView将接受所有网站的安全证书。默认行为是执行handler.cancel()。
注意,在这个方法中执行相应操作后,后续出现的SSL错误也会采取同样的行为。
onFormResubmission
//在WebView需要重新提交表单时触发(使用POST请求)
//dontResend:不重发时使用这个Message。
//resend:需要重发时使用这个Message。
public void onFormResubmission(WebView view, Message dontResend,Message resend);
默认不执行重发操作。可选的两种行为:
- dontResend.sendToTarget():不重发。
- resend.sendToTarget();重发。
这个提供一个简单的应用场景:页面中有一个搜索框,用户在搜索框中输入数据后点击查询按钮,然后网页通过POST请求将数据传递给服务器。服务器将查询结果返回,WebView则展示相应的数据。问题在于,如果此时点击刷新按钮(reload),刷新后的页面将会是一片空白。这个因为刷新前通过POST请求发送的数据在reload后没有被重新发送到服务器,服务器也就无法返回刷新前的结果了。onFormResubmission方法正是用于解决这个问题的,只要执行resend.sendToTarget()
,POST数据就会被重发,WebView的显示结果就不会受到刷新的影响了。
doUpdateVisitedHistory
//当WebView加载url时会触发(这时可以更新网页浏览历史)
//url:正在加载的url。
//isReload:如果当前url正在重新加载,isReload将会是true,否则为false。
public void doUpdateVisitedHistory(WebView view, String url,boolean isReload);
注意,点击链接、网页重定向、刷新页面(重新加载)、网页的前进和后退都会触发这个方法。此外,经过实际验证,得知isReload
只有在使用reload
方法重新加载当前页面时才会是true,其他情形都是false。
onReceivedClientCertRequest
//通知WebView处理SSL客户端证书请求 [Android 5.0(API 21)及以上可用]
//request:封装证书请求。
public void onReceivedClientCertRequest(WebView view, ClientCertRequest request);
request有三种处理方式:
- request.cancel():取消本次请求。默认行为。
- request.proceed():执行本次请求。需要传入私钥和client certificate chain。
- request.ignore():忽略本次请求。
注意,执行cancel和proceed都会导致WebView记住本次的选择,后续处理同一主机和端口的证书请求时,onReceivedClientCertRequest方法将不会再被触发。
注意,这个方法会在UI线程中回调,此时网络连接处于暂停状态。
onReceivedHttpAuthRequest
//通知WebView处理http认证请求
//handler:认证处理器。
//host:主机名。
public void onReceivedHttpAuthRequest(WebView view,HttpAuthHandler handler, String host, String realm);
handler有两种处理方式:
- handler.cancel():取消本次请求。默认行为。
- handler.procee():执行本次请求。需要传入账号和密码。
onReceivedLoginRequest
//当出现一个自动登录请求时会触发
//account:账号。
//args:其他的认证信息。
public void onReceivedLoginRequest(WebView view, String realm,String account, String args);
shouldOverrideKeyEvent
//通知应用处理按键点击事件
//event:按键点击事件。
public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event);
如果返回true,WebView将不会处理这个按键事件;如果返回false,WebView将处理这个按键事件。默认返回false。
onUnhandledKeyEvent
//当按键点击事件未被WebView处理时触发
//event:按键点击事件。
public void onUnhandledKeyEvent(WebView view, KeyEvent event);
如果shouldOverrideKeyEvent返回true,按键点击事件就会触发这个方法,在这个方法中可以执行一些自定义的操作。
onScaleChanged
//当WebView的缩放比发生变化时触发
//oldScale:旧的缩放比。
//newScale:新的缩放比。
public void onScaleChanged(WebView view, float oldScale, float newScale);
4.WebChromeClient
onProgressChanged
//通知应用网页加载进度已经改变
//newProgress:网页当前的加载进度(数值为0-100)
public void onProgressChanged(WebView view, int newProgress);
onReceivedTitle
//通知应用网页标题已经改变
//title:当前网页的标题
public void onReceivedTitle(WebView view, String title);
onReceivedIcon
//通知应用网页图标已经改变
//icon:当前网页的图标
public void onReceivedIcon(WebView view, Bitmap icon);
onJsAlert
//当Javascript调用alert方法时触发
//message:alert弹出窗口中的提示信息(提示或警告信息对话框,仅一个确认按钮)
//result:向网页中的Javascript代码反馈本次操作结果
public boolean onJsAlert(WebView view, String url, String message,JsResult result);
result.confirm代表点击了确定按钮,result.cancel代表点击了取消按钮。
在这个回调方法中,可以实现符合应用风格的对话框(通过AlertDialog实现),这可以给用户更棒的视觉体验。需要注意,这个方法有一个boolean返回值。如果返回true,代表Android应用已经对弹窗进行了处理,Javascript代码不必再弹出窗口了;反之,代表本次弹窗请求未被处理,网页将按照默认效果弹出窗口。
onJsConfirm
//当Javascript调用confirm方法时触发
//message:confirm弹出窗口中的提示信息(确认对话框,有确认、取消两个按钮)
//result:向网页中的Javascript代码反馈本次操作结果
public boolean onJsConfirm(WebView view, String url, String message,JsResult result);
result.confirm代表点击了确定按钮,result.cancel代表点击了取消按钮。
在这个回调方法中,可以实现符合应用风格的对话框(通过AlertDialog实现),这可以给用户更棒的视觉体验。需要注意,这个方法有一个boolean返回值。如果返回true,代表Android应用已经对弹窗进行了处理,Javascript代码不必再弹出窗口了;反之,代表本次弹窗请求未被处理,网页将按照默认效果弹出窗口。
onJsPrompt
//当Javascript调用prompt方法时触发
//message:prompt弹出窗口中的提示信息(输入信息对话框,有一个输入框,还有确认、取消两个按钮)
//defaultValue:输入框中的默认信息
//result:向网页中的Javascript代码反馈本次操作结果
public boolean onJsPrompt(WebView view, String url, String message,String defaultValue, JsPromptResult result);
result.confirm代表点击了确定按钮,result.cancel代表点击了取消按钮。
在这个回调方法中,可以实现符合应用风格的对话框(通过AlertDialog实现),这可以给用户更棒的视觉体验。需要注意,这个方法有一个boolean返回值。如果返回true,代表Android应用已经对弹窗进行了处理,Javascript代码不必再弹出窗口了;反之,代表本次弹窗请求未被处理,网页将按照默认效果弹出窗口。
onGeolocationPermissionsShowPrompt
//通知应用当前网页中的JS代码正在尝试使用Geolocation API,但是并未取得定位权限
//origin:网页来源。
//callback:回调器。用于设置权限状态。
public void onGeolocationPermissionsShowPrompt(String origin,GeolocationPermissions.Callback callback);
在这个方法中可以为WebView获取相应的定位权限,需要在AndroidManifest文件中声明android.Manifest.permission.ACCESS_COARSE_LOCATION和android.Manifest.permission.ACCESS_FINE_LOCATION两个权限。需要注意,Android6.0及以上引入了运行时权限的概念。定位属于危险权限,需要在使用时手动获取。因此可以在这个回调方法中弹出一个请求定位的提示对话框(AlertDialog),在用户选择确定后获得相应权限。
callback通过invoke方法为网页设置定位权限状态,有以下两种操作:
- callback.invoke(origin,true,false):授予网页定位权限。
- callback.invoke(origin,false,false):不授予网页定位权限。
invoke方法的第一个参数是请求的来源,第二个参数代表是否授予定位权限。invoke还有第三个参数,代表是否记住本次选择。如果为false,WebView将记住本次的选择,下次同一来源的请求将自动采取相同的选择;否则,每次网页请求定位权限的时候都会触发onGeolocationPermissionsShowPrompt方法让用户做出选择。
onGeolocationPermissionsHidePrompt
//通知应用之前的定位权限请求已经取消
public void onGeolocationPermissionsHidePrompt();
这个方法对应着onGeolocationPermissionsShowPrompt,主要是用于关闭相应提示对话框(AlertDialog)。
onShowFileChooser
//通知应用显示文件选择器
//filePathCallback:用于返回已选择的文件路径列表。
//fileChooserParams:文件选择器的打开模式。可选值:MODE_OPEN、MODE_OPEN_MULTIPLE、MODE_OPEN_FOLDER、MODE_SAVE。
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams);
这个方法会在点击<input type="file">
标签时触发,可以用于在应用中弹出自定义的文件选择框。如果需要取消本次文件选择,就应该调用filePathCallback.onReceiveValue(null)
并返回true。
getVisitedHistory
//获得已访问的所有url历史,用于链接着色
public void getVisitedHistory(ValueCallback<String[]> callback);
getDefaultVideoPoster
//返回默认视频略缩图
public Bitmap getDefaultVideoPoster();
通过这个方法可以改变网页中video的默认略缩图。如果网页中的<video>
标签未设置poster属性,这个默认视频略缩图就会被使用。
getVideoLoadingProgressView
//返回视频缓冲进度条
public View getVideoLoadingProgressView();
通过这个方法可以改变网页中视频的缓冲进度条(需要返回View对象),一般是圆形进度条样式。
onReceivedTouchIconUrl
//通知应用获得了一个TouchIcon的url
//precomposed:如果为true,表示这个TouchIcon是预组合。指定为预组合的图标不会被设备执行圆角化等视觉处理。
public void onReceivedTouchIconUrl(WebView view, String url,boolean precomposed);
所谓的TouchIcon,是指支持将网页添加到桌面需要的图标,最早是由苹果提出的一种技术标准。在HTML网页中,指定了TouchIcon的链接格式大致如下:
<!--非预组合-->
<link rel="apple-touch-icon" href="touch-icon-iphone.png">
<!--预组合-->
<link rel="apple-touch-icon-precomposed" href="touch-icon-iphone.png">
onShowCustomView
//通知应用当前网页进入了全屏模式
public void onShowCustomView(View view, CustomViewCallback callback);
onHideCustomView
//通知应用当前网页退出了全屏模式
public void onHideCustomView();
onJsBeforeUnload
//通知客户端弹出对话框提示用户是否要离开当前页面
//message:提示信息。
//result:为底层的Javascript传递返回值(true或false)
public boolean onJsBeforeUnload(WebView view, String url, String message,JsResult result);
这个方法会在当前网页发生导航操作(后退、前进、跳转到其他链接、关闭当前页面)时触发。如果这个方法返回true,WebView就需要自行弹出提示对话框,并使用result参数向底层的Javascript传递用户的操作结果。result可以执行两种操作:
- result.confirm():代表离开当前页面。
- result.cancel():代表留在当前页面,取消本次导航请求。
默认情况下,这个方法会返回false,这时就相当于执行了result.confirm(),即离开当前页面。
onCreateWindow
//请求应用创建一个新的窗口
public boolean onCreateWindow(WebView view, boolean isDialog,boolean isUserGesture, Message resultMsg);
如果应用同意创建新的窗口,就需要在这个方法中返回true,并且创建一个新的WebView承载这个window(WebView需要插入到View视图系统中)。如果返回false,代表忽略本次请求。
onCloseWindow
//通知应用关闭给定的WebView
//window:给定的WebView。
public void onCloseWindow(WebView window);
如果有必要的话,还需要将给定的WebView从View视图系统中移除。注意,这个方法执行的时候会停止给定WebView中所有的加载行为。
onRequestFocus
//请求视图焦点
public void onRequestFocus(WebView view);
onPermissionRequest
//通知应用WebView正在请求某些资源权限
public void onPermissionRequest(PermissionRequest request);
通过request可以执行两种操作:
- request.deny():默认行为。拒绝本次权限请求。
- request.grant(String[] resources):授予相应的权限。
可选的权限:RESOURCE_VIDEO_CAPTURE、RESOURCE_AUDIO_CAPTURE、RESOURCE_PROTECTED_MEDIA_ID、RESOURCE_MIDI_SYSEX。
onPermissionRequestCanceled
//通知应用请求资源权限的操作已经取消
public void onPermissionRequestCanceled(PermissionRequest request);
这个方法对应着onPermissionRequest。可以在这个方法中执行一些收尾操作,比如关闭提示对话框。
onConsoleMessage
//为应用提交Javascript的日志信息
//consoleMessage:封装日志信息。
public boolean onConsoleMessage(ConsoleMessage consoleMessage);
可以在这个方法中对日志信息进行个性化设置。
5.CookieManager
getInstance
//获得一个CookieManager实例 [静态方法]
public static CookieManager getInstance();
getCookie
//根据url获取Cookie
//return:以字符串形式返回Cookie
public abstract String getCookie(String url);
setCookie
//为url设置Cookie
//value:字符串形式的Cookie
public abstract void setCookie(String url, String value);
//为url设置Cookie(异步执行)
//value:字符串形式的Cookie
//callback:回调器。在对Cookie的设置操作结束后,会回调onReceiveValue方法。
public abstract void setCookie(String url, String value, ValueCallback<Boolean> callback);
callback的onReceiveValue方法获取的参数如果是true,代表本次设置成功,否则代表设置失败。如果并不关心执行结果,为callback参数传入null即可。
setAcceptCookie
//设置WebView是否允许使用Cookie
//accept:是否允许。
public abstract void setAcceptCookie(boolean accept);
注意,这个方法针对的是当前应用的所有WebView。
setAcceptThirdPartyCookies
//设置WebView是否允许设置第三方Cookie
//webview:接受本次Cookie策略的WebView对象。
//accept:是否允许。Android 5.0(API 21)以下默认为true,Android 5.0及以上默认为false。
public abstract void setAcceptThirdPartyCookies(WebView webview, boolean accept);
可以为每个WebView单独设置相应的第三方Cookie策略。注意,需要setAcceptCookie方法传入true时,这个方法才有作用。
removeSessionCookies
//移除所有Session Cookies [Android 5.0(API 21)已弃用]
public abstract void removeSessionCookie();
//移除所有Session Cookies(异步执行) [Android 5.0(API 21)及以上可用]
//callback:回调器。在执行完移除操作后,会回调onReceiveValue方法。
public abstract void removeSessionCookies(ValueCallback<Boolean> callback);
callback的onReceiveValue方法获取的参数如果是true,代表执行成功,否则代表执行失败。如果并不关心执行结果,为callback参数传入null即可。
removeAllCookie
//移除所有Cookies [Android 5.0(API 21)已弃用]
public abstract void removeAllCookie();
//移除所有Cookies(异步执行) [Android 5.0(API 21)及以上可用]
//callback:回调器。在执行完移除操作后,会回调onReceiveValue方法。
public abstract void removeAllCookies(ValueCallback<Boolean> callback);
callback的onReceiveValue方法获取的参数如果是true,代表执行成功,否则代表执行失败。如果并不关心执行结果,为callback参数传入null即可。
hasCookies
//判断是否存在储存的Cookies
public abstract boolean hasCookies();
removeExpiredCookie
//移除过期的Cookies [Android 5.0(API 21)已弃用]
public abstract void removeExpiredCookie();
在Android 5.0及以上,WebView会自动移除过期的Cookies。
6.WebResourceRequest
getUrl
//获取本次请求的url(Uri形式)
Uri getUrl();
isForMainFrame
//判断本次请求是否是针对主页面的
boolean isForMainFrame();
如果是嵌入页面(iframe)发起的请求,这个方法就会返回false。
isRedirect
//判断本次请求是否为服务器端发起的重定向请求
boolean isRedirect();
getMethod
//获取本次请求的方式(如POST、GET等)
String getMethod();
getRequestHeaders
//获取本次请求的请求头
Map<String, String> getRequestHeaders();
这个方法会返回Map类型的数据,因此可以通过键值对的方式获取相应的请求头数据。
7.WebResourceResponse
setMimeType
//设置response的mimeType属性
//mimetype:如"text/html"。
public void setMimeType(String mimeType);
setEncoding
/设置response的编码
//encoding:如"UTF-8"。
public void setEncoding(String encoding);
getStatusCode
//获取本次响应的状态码
public int getStatusCode();
getReasonPhrase
//获取本次响应的状态描述信息
public String getReasonPhrase();
setStatusCodeAndReasonPhrase
//设置response的状态码和状态描述信息
public void setStatusCodeAndReasonPhrase(int statusCode, String reasonPhrase);
getResponseHeaders
//获取响应头信息
public Map<String, String> getResponseHeaders();
setData
//设置response的data数据
//data:输入流对象。不可以是StringBufferInputStream。
public void setData(InputStream data);
8.WebResourceError
getErrorCode
//获取错误码
public abstract int getErrorCode();
getDescription
//获取错误描述信息
public abstract CharSequence getDescription();
9.SslErrorHandler
proceed
//接收SSL证书
public void proceed();
cancel
//取消本次SSL请求
public void cancel() ;