WebView详解
在安卓开发中可以使用WebView来显示和渲染Web页面,直接使用html文件(网络上或本地assets中)作布局同时可以JavaScript交互调用,下面来详细介绍下webview的常见用法。
基本用法
1. Webview自身的常见方法
布局文件配置WebView
<WebView
android:id="@+id/wv_news_detail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
WebView加载网页
//方式1. 加载一个网页:
mWebview.loadUrl("http://www.csdn.net/");
//方式2:加载apk包中的html页面
mWebview.loadUrl("file:///android_asset/test.html");
//方式3:加载手机本地的html页面
mWebview.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
2. Webview的最常用的子类 (WebSettings类、WebViewClient类、WebChromeClient类)
- WebSettings
//声明WebSettings子类
WebSettings webSettings = webView.getSettings();
//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
webSettings.setJavaScriptEnabled(true);
//支持插件
webSettings.setPluginsEnabled(true);
//设置自适应屏幕,两者合用
webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
//缩放操作
webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
//其他细节操作
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
webSettings.setAllowFileAccess(true); //设置可以访问文件
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
- WebViewClient类(作用:处理各种通知 & 请求事件)
mWebview.setWebViewClient(new WebViewClient() {
//打开网页时不调用系统浏览器, 而是在本WebView中显示;在网页上的所有加载都经过这个方法,这个函数我们可以做很多操作。
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
//开始载入页面调用的,我们可以设定一个loading的页面,告诉用户程序在等待网络响应。
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
//设定加载结束的操作
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
//在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
}
//加载页面的服务器出现错误时(如404)调用
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
//判断错误码,显示对应的界面
}
});
- WebChromeClient类(辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等)
mWebview.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress < 100) {
String progress = newProgress + "%";
} else {
}
}
//获取Web页中的标题
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
});
3. Android和Js的交互
如果Js和Android实现了交互, 那么我们就可以在网页中随意调用本地的Java代码, 也就是实现了WebView和本地代码的交互. 一旦WebView可以操作Android本地代码, 那么WebView的功能就会更加强大,以后我们直接在一个WebView中就几乎可以实现Android的所有功能.
Js调用Android
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);//开启js
mWebView.loadUrl("file:///android_asset/demo.html");//加载本地网页
mWebView.setWebChromeClient(new WebChromeClient());//此行代码可以保证js的alert弹窗正常弹出
//核心方法, 用于处理js被执行后的回调
mWebView.addJavascriptInterface(new JsCallback() {
@JavascriptInterface//注意:此处一定要加该注解,否则在4.1+系统上运行失败
@Override
public void onJsCallback() {
System.out.println("js调用Android啦");
}
}, "demo");//参1是回调接口的实现;参2是js回调对象的名称
//定义回调接口
public interface JsCallback {
public void onJsCallback();
}
Android调用Js
//直接使用webview加载js就可以了
mWebView.loadUrl("javascript:wave()");
html代码
<head>
<title>js调用android原生代码</title>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<meta id="viewport" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui">
<script type="text/javascript">
function javacalljs(){
document.getElementById("content").innerHTML +=
"<br\>java调用了js函数,无参";
}
<!--这里取到的是 android端传过来的数据-->
function javacalljswithargs(data){
document.getElementById("content").innerHTML +=
("<br\>"+data);
}
function wave() {
alert("Android调用Js啦");
}
/* This function is invoked by the activity */
function wave() {
alert("Android调用Js啦");
}
</script>
</head>
<body>
<br/><br/>
<li><a onClick="window.injectedObject.startFunction()">点击调用java代码</a></li>
<!--可以将android端传过来的数据,处理后,放在这里再传给android端-->
<li><a onClick="window.injectedObject.startFunction('我是网页传出来的数据')">点击调用java代码并传递参数</a></li><br/>
<div id="content">内容显示</div>
</body>
</html>
4. 需要注意的几个方面
//销毁Webview:在 Activity 销毁( WebView )的时候,先让 WebView 加载null内容,然后移除 WebView,再销毁 WebView,最后置空
//但是注意:webview调用destory时,webview仍绑定在Activity上
//这是由于自定义webview构建时传入了该Activity的context对象
//因此需要先从父容器中移除webview,然后再销毁webview:
@Override
protected void onDestroy() {
if (mWebView != null) {
mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
mWebView.clearHistory();
((ViewGroup) mWebView.getParent()).removeView(mWebView);
mWebView.destroy();
mWebView = null;
}
super.onDestroy();
}
在点击Back键控制网页后退,解决直接关闭问题
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
代码地址:https://github.com/cruiseliang/WebViewStudy
参考文章:
https://www.jianshu.com/p/1b8779401db7