在实际开发中,经常会与遇到很多需求,我们用原生的android去开发难度会增大,很费功夫,甚至还会无法满足(比如xxx详情页面或者一些展示效果复杂的页面)。然而,这些很多在web端开发就变得相对简单很多。在Android中就提供了一个WebView,可以展示web页面,也可以做到android和js的交互,这样就能很方便我们的开发工作。今天开始就来好好学习一下WebView的简单使用,和android和js的简单交互。
WebView简介
A View that displays web pages. This class is the basis upon which you
can roll your own web browser or simply display some online content within your Activity.
It uses the WebKit rendering engine to display
web pages and includes methods to navigate forward and backward
through a history, zoom in and out, perform text searches and more.
WebView是Android中的一个原生UI控件,它是一个基于webkit引擎、展现web页面的控件。Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome。
WebView的功能非常的强大,它可以加载无论是远程的网页url还是本地assets资源中的html网页文件。并且WebView还能当作java代码和js代码之间的桥梁,实现两者之间的交互功能。
WebView基本方法(API)
-
WebView自身方法
1,基础
// 获取当前页面的URL
public String getUrl();
// 获取当前页面的原始URL(重定向后可能当前url不同)
// 就是http headers的Referer参数,loadUrl时为null
/**
* Gets the original URL for the current page. This is not always the same
* as the URL passed to WebViewClient.onPageStarted because although the
* load for that URL has begun, the current page may not have changed.
* Also, there may have been redirects resulting in a different URL to that
* originally requested.
*/
public String getOriginalUrl();
// 获取当前页面的标题Title
public String getTitle();
// 获取当前页面的favicon
public Bitmap getFavicon();
/**
* Gets the touch icon URL for the apple-touch-icon <link> element, or
* a URL on this site's server pointing to the standard location of a
* touch icon.
*/
public String getTouchIconUrl();
// 获取当前页面的加载进度
public int getProgress();
//Gets the height of the HTML content.获取HTML内容的高度。
public int getContentHeight();
//Gets the width of the HTML content.获取HTML内容的宽度。
public int getContentWidth();
// 通知WebView内核网络状态
// 用于设置JS属性`window.navigator.isOnline`和产生HTML5事件`online/offline`
public void setNetworkAvailable(boolean networkUp)
// 设置初始缩放比例
public void setInitialScale(int scaleInPercent);
2,网页加载
// 加载指定URL的网页
public void loadUrl(String url);
// 加载指定URL的网页,携带http headers请求头部
public void loadUrl(String url, Map<String, String> additionalHttpHeaders);
/**
* Loads the URL with postData using "POST" method into this WebView. If url
* is not a network URL, it will be loaded with {@link #loadUrl(String)}
* instead, ignoring the postData param.
*
* @param url the URL of the resource to load
* @param postData the data will be passed to "POST" request, which must be
* be "application/x-www-form-urlencoded" encoded.
*/
// 使用POST请求加载指定的网页
public void postUrl(String url, byte[] postData);
// 重新加载当前网页
public void reload();
/*
* @param data a String of data in the given encoding
* @param mimeType the MIME type of the data, e.g. 'text/html'
* @param encoding the encoding of the data
*/
// 加载内容 eg:mWebView.loadData(html, "text/html", "UTF-8");
public void loadData(String data, String mimeType, String encoding);
// 使用baseUrl加载内容
public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl);
3,WebView状态
//激活WebView,是其能正常执行网页的响应
public void onResume();
//当页面被失去焦点被切换到后台不可见状态,需要执行onPause
//通过onPause动作通知内核暂停所有可以被暂停的动作,比如动画,地理位置。不暂停JavaScript,要在全局范围内暂停JavaScript,请使用{@link #pauseTimers}
public void onPause();
//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview
//它会暂停所有webview的layout,parsing,javascript,timer。降低CPU功耗。
public void pauseTimers();
//恢复pauseTimers状态
public void resumeTimers();
//销毁Webview
//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview
//但是注意:webview调用destory时,webview仍绑定在Activity上
//这是由于自定义webview构建时传入了该Activity的context对象
//因此需要先从父容器中移除webview,然后再销毁webview:
rootLayout.removeView(webView);
public void destroy();
4,网页导航(页面前进/回退)
/**
* Gets the WebBackForwardList for this WebView. This contains the
* back/forward list for use in querying each item in the history stack.
* This is a copy of the private WebBackForwardList so it contains only a
* snapshot of the current state. Multiple calls to this method may return
* different objects. The object returned from this method will not be
* updated to reflect any new state.
*/
// 复制一份BackForwardList,这个列表中保护了所有“前进/后退”的页面,可以用于查找每一项
public WebBackForwardList copyBackForwardList();
// 是否可后退
public boolean canGoBack();
// 是否可前进
public boolean canGoForward();
// 是否可前进/后退steps页,大于0表示前进小于0表示后退
// steps移动的页数
public boolean canGoBackOrForward(int steps);
// 后退一页
public void goBack();
// 前进一页
public void goForward();
// 前进/后退steps页,大于0表示前进小于0表示后退
public void goBackOrForward(int steps);
// 清除当前webview访问的历史记录
public void clearHistory();
android中如何使用back键控制页面回退。 例子:
//在有webview的activity中重写onKeyDown方法
//判断当keyCode == KEYCODE_BACK(及所点击的按钮是back键)
//并且mWebView.canGoBack() == ture(及可以会退一个页面),
//这样就只回退一个页面,然后时间就会被消费掉。
//否则,执行父类的onKeyDown方法(及acticity被销毁)。
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
5,清除缓存数据
// 清除网页缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序
public void clearCache(boolean includeDiskFiles);
//清除当前webview访问的历史记录
//只会清除webview访问历史记录里的所有记录,除了当前访问记录
public void clearHistory()
// 清除自动完成填充的表单数据
public void clearFormData();
// 清除SSL偏好
public void clearSslPreferences();
6,Javascript
// 注入Javascript对象
public void addJavascriptInterface(Object object, String name);
// 移除已注入的Javascript对象,下次加载或刷新页面时生效
public void removeJavascriptInterface(String name);
// 对传入的JS表达式求值,通过resultCallback返回结果
// 此函数添加于API19,必须在UI线程中调用,回调也将在UI线程
public void evaluateJavascript(String script, ValueCallback<String> resultCallback)
7,页面显示效果
// 上翻一页,即向上滚动WebView高度的一半
public void pageUp(boolean top);
// 下翻一页,即向下滚动WebView高度的一半
public void pageDown(boolean bottom);
// 按给定比例缩放
public void zoomBy(float factor);
// 放大
public boolean zoomIn();
// 缩放
public boolean zoomOut();
8,其他方法
// 设置网页查找结果回调
public void setFindListener(FindListener listener);
// 异步执行查找网页内包含的字符串并设置高亮,查找结果会回调.
public void findAllAsync (String find);
// 查找下一个匹配的字符串
public void findNext (boolean forward);
// 清除网页查找的高亮匹配字符串
public void clearMatches();
// 保存网页(.html)到指定文件
public void saveWebArchive(String filename);
// 保存网页(.html)到文件
public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback);
// 查询文档中是否有图片,查询结果将被发送到msg.getTarget()
// 如果包含图片,msg.arg1 为1,否则为0
public void documentHasImages(Message msg);
// 请求最近轻叩(tapped)的 锚点/图像 元素的URL,查询结果将被发送到msg.getTarget()
// msg.getData()中的url是锚点的href属性,title是锚点的文本,src是图像的src
public void requestFocusNodeHref(Message msg);
// 请求最近触摸(touched)的 图像元素的URL,查询结果将被发送到msg.getTarget()
// msg.getData()中的url是图像链接
public void requestImageRef(Message msg)
// 清除证书请求偏好,添加于API21
// 在WebView收到`android.security.STORAGE_CHANGED` Intent时会自动清除
public static void clearClientCertPreferences(Runnable onCleared)
// 开启网页内容(js,css,html...)调试模式,添加于API19
public static void setWebContentsDebuggingEnabled(boolean enabled)
-
WebSettings
WebSettings是一个对webView进行配置和管理的类。
/**
* Manages settings state for a WebView. When a WebView is first created, it
* obtains a set of default settings. These default settings will be returned
* from any getter call. A WebSettings object obtained from
* WebView.getSettings() is tied to the life of the WebView. If a WebView has
* been destroyed, any method call on WebSettings will throw an
* IllegalStateException.
*/
//声明WebSettings
WebSettings settings = web.getSettings();
// 是否支持Javascript,默认值false,
//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
settings.setJavaScriptEnabled(true);
// 存储(storage)
// 启用HTML5 DOM storage API,默认值 false
settings.setDomStorageEnabled(true);
// 定位(location)
settings.setGeolocationEnabled(true);
// 是否保存表单数据
settings.setSaveFormData(true);
// 是否当webview调用requestFocus时为页面的某个元素设置焦点,默认值 true
settings.setNeedInitialFocus(true);
// 页面通过`<meta name="viewport" ... />`自适应手机屏幕
//进行配置后,如果网页针对移动设备进行了自适应处理,那么页面将缩放到最合适的大小,通常这将带来更好的视觉效果。
settings.setUseWideViewPort(true);
// 是否使用overview mode加载页面,默认值 false
// 当页面宽度大于WebView宽度时,缩小使页面宽度等于WebView宽度
settings.setLoadWithOverviewMode(true);
// 布局算法
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
// 是否支持多窗口,默认值false
settings.setSupportMultipleWindows(false);
// 是否可用Javascript(window.open)打开窗口,默认值 false
settings.setJavaScriptCanOpenWindowsAutomatically(false);
// 资源访问
settings.setAllowContentAccess(true); // 是否可访问Content Provider的资源,默认值 true
settings.setAllowFileAccess(true); // 是否可访问本地文件,默认值 true
// 是否允许通过file url加载的Javascript读取本地文件,默认值 false
settings.setAllowFileAccessFromFileURLs(false);
// 是否允许通过file url加载的Javascript读取全部资源(包括文件,http,https),默认值 false
settings.setAllowUniversalAccessFromFileURLs(false);
// 资源加载
settings.setLoadsImagesAutomatically(true); // 是否自动加载图片
settings.setBlockNetworkImage(false); // 禁止加载网络图片
settings.setBlockNetworkLoads(false); // 禁止加载所有网络资源
// 缩放(zoom)
//进行配置后,就可以通过多指的捏合操作对网页执行缩放了。
//另外提一下,之所以调用setDisplayZoomControls(false)隐藏虚拟缩放按钮,主要是为了美观。
//因为可以使用多指触摸执行缩放操作,就没必要单独提供按钮了(外观比较丑)。
//当然,如果有必要显示按钮,传入true即可,并不影响最终的缩放功能。
settings.setSupportZoom(true); // 是否支持缩放
settings.setBuiltInZoomControls(false); // 是否使用内置缩放机制
settings.setDisplayZoomControls(true); // 是否显示内置缩放控件。但是要注意,setDisplayZoomControls(true)在某些系统版本中可能会导致应用出现意外崩溃
// 默认文本编码,默认值 "UTF-8"
settings.setDefaultTextEncodingName("UTF-8");
settings.setDefaultFontSize(16); // 默认文字尺寸,默认值16,取值范围1-72
settings.setDefaultFixedFontSize(16); // 默认等宽字体尺寸,默认值16
settings.setMinimumFontSize(8); // 最小文字尺寸,默认值 8
settings.setMinimumLogicalFontSize(8); // 最小文字逻辑尺寸,默认值 8
settings.setTextZoom(100); // 文字缩放百分比,默认值 100
// 字体
settings.setStandardFontFamily("sans-serif"); // 标准字体,默认值 "sans-serif"
settings.setSerifFontFamily("serif"); // 衬线字体,默认值 "serif"
settings.setSansSerifFontFamily("sans-serif"); // 无衬线字体,默认值 "sans-serif"
settings.setFixedFontFamily("monospace"); // 等宽字体,默认值 "monospace"
settings.setCursiveFontFamily("cursive"); // 手写体(草书),默认值 "cursive"
settings.setFantasyFontFamily("fantasy"); // 幻想体,默认值 "fantasy"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 用户是否需要通过手势播放媒体(不会自动播放),默认值 true
settings.setMediaPlaybackRequiresUserGesture(true);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 5.0以上允许加载http和https混合的页面(5.0以下默认允许,5.0+默认禁止)
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 是否在离开屏幕时光栅化(会增加内存消耗),默认值 false
settings.setOffscreenPreRaster(false);
}
if (isNetworkConnected(context)) {
// 根据cache-control决定是否从网络上取数据
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
} else {
// 没网,离线加载,优先加载缓存(即使已经过期)
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
/*
WebView是原生支持缓存的,我们只需要设置合适的缓存模式即可。
setCacheMode方法需要一个int类型的参数,系统提供了四种可选值,
区别如下:
LOAD_DEFAULT:默认值。当存在缓存且未过期时加载缓存数据,否则通过网络加载数据。
LOAD_NO_CACHE:不使用缓存。仅通过网络加载数据。
LOAD_CACHE_ONLY:只使用缓存。仅加载缓存数据,不通过网络加载数据。
LOAD_CACHE_ELSE_NETWORK:只要存在缓存,不管是够过期都加载缓存数据,否则通过网络极加载数据。
*/
// deprecated。设置渲染线程的优先级。与其他设置不同,每个进程只需调用一次
settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
//设置保存数据库存储API数据库的路径。
//为了使数据库存储API正常工作,此方法必须使用应用程序可以写入的路径进行调用。
//这个方法应该只调用一次:重复的调用将被忽略。
settings.setDatabasePath(context.getDir("database", Context.MODE_PRIVATE).getPath());
//设置应该保存地理定位数据库的路径。
//用于持久化地理定位权限和缓存位置,
//方法必须用应用程序可以写入的路径调用。
settings.setGeolocationDatabasePath(context.getFilesDir().getPath());
WebSettings可设置的属性非常的多,通常情况下,我们大部分保持它原有的默认值即可。只需修改一些我们需要的属性方法。
-
WebViewClient
进行中...
-
WebChromeClient
进行中...
代码示例
进行中...
网友评论