一、 WebView的基本介绍
WebView是Android开发中的一个非常重要的控件,它可以让我们在应用程序中加载并显示网页、图片等替代在浏览器中访问。不仅如此,WebView也可以实现JavaScript与Java之间的相互调用、页面内容的持久化、缓存和离线存储等。
1、通过XML定义WebView
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
2、通过代码定义WebView
WebView webView = new WebView(this);
setContentView(webView);
webView.loadUrl("http://www.example.com");
二、 WebView的设置与用法
1、设置WebViewClient和WebChromeClient
使用setWebViewClient()设置WebViewClient可以让WebView在当前应用程序中加载网页,而不是跳转到系统浏览器中。
使用setWebChromeClient()设置WebChromeClient可以接收WebView的一些通知信息,如网页标题改变、加载进度等。
webView.setWebViewClient(new WebViewClient() {
// 当页面加载完毕后回调
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
});
2、WebView的基本设置
WebView提供了很多基本设置,包括加载缓存、JavaScript支持、缩放控制等。
// 启用JavaScript支持
webView.getSettings().setJavaScriptEnabled(true);
// 设置允许访问文件
webView.getSettings().setAllowFileAccess(true);
// 不缩放
webView.getSettings().setBuiltInZoomControls(false);
// 开启DOM storage
webView.getSettings().setDomStorageEnabled(true);
// 缓存模式:不使用缓存
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// 支持缩放
webView.getSettings().setSupportZoom(true);
webView.getSettings().setUseWideViewPort(true);
3、WebView的前进与后退
我们可以通过调用goBack()和goForward()方法让WebView前进或后退页面。
// 前进
if (webView.canGoForward()) {
webView.goForward();
}
// 后退
if (webView.canGoBack()) {
webView.goBack();
}
4、JavaScript与Java的交互
如果需要在WebView中执行一些JavaScript脚本并获取它们的返回结果,我们可以通过调用evaluateJavascript()方法实现。
而在WebView中调用Java方法,则需要通过JSBridge注入JavaScript代码实现。
(1)evaluateJavascript()方法
evaluateJavascript()方法有两个参数:要执行的JavaScript代码和返回结果的回调函数。下面是一个简单的例子,它使用evaluateJavascript()方法获取网页中的标题信息。
// 加载完成监听器
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// 获取标题
webView.evaluateJavascript("javascript:document.title", new ValueCallback
() {
@Override
public void onReceiveValue(String value) {
Log.d(TAG, "onReceiveValue: " + value);
}
});
}
});
(2)JSBridge实现JavaScript与Java的互调
JSBridge是一种基于WebView的JavaScript与Java相互调用桥梁,它可以在WebView中inject一个JavaScript对象,在JavaScript中调用Java类的方法、获取Java对象的属性等。
下面是一个简单的例子,它演示了如何在JavaScript中调用Android中的一个方法,方法接收一个字符串参数并返回一个字符串结果。
// 添加JSBridge
WebView.addJavascriptInterface(new Object() {
@JavascriptInterface
public String callAndroid(String arg) {
// 调用方法并返回结果
return "Hello, " + arg;
}
}, "jsBridge");
// 在JavaScript中调用Android方法
webView.loadUrl("javascript:alert(jsBridge.callAndroid('World!'));");
三、 WebView的优化
1、减少不必要的加载
WebView默认会加载所有资源,包括图片、样式、脚本等,这样会导致加载速度变慢、消耗流量增加。因此,我们应该尽量减少不必要的加载。
可以通过以下两种方式实现:
(1)使用WebViewClient中的shouldInterceptRequest()方法截取资源请求,返回null则表示不加载该资源;
(2)使用WebSettings中的setBlockNetworkImage()方法禁止加载图片。
2、启用缓存
可以通过WebSettings中的setAppCacheEnabled()、setCacheMode()等方法来启用WebView缓存。例如,以下代码启用了应用缓存、开启DOM storage和启用LocalStorage:
// 启用应用缓存
webView.getSettings().setAppCacheEnabled(true);
// 设置缓存模式
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
// 启用DOM storage
webView.getSettings().setDomStorageEnabled(true);
// 启用LocalStorage
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setDatabasePath(getApplicationContext().getCacheDir().getAbsolutePath() + "/database/");
3、WebView的复用
WebView的创建和销毁是很耗费资源的操作,因此我们应该尽量避免创建和销毁WebView。可以通过在Activity中创建一个单例的WebView对象,然后在需要使用WebView的地方调用该对象即可。
以下是一个简单的例子,它在Activity中创建了一个单例的WebView对象,并提供了一个start方法用于加载指定的URL。
public class WebViewManager {
private static volatile WebViewManager instance;
private WebView webView;
private WebViewManager(Context context) {
webView = new WebView(context);
webView.setWebViewClient(new WebViewClient() {
// ...
});
}
public static WebViewManager getInstance(Context context) {
if (instance == null) {
synchronized (WebViewManager.class) {
if (instance == null) {
instance = new WebViewManager(context);
}
}
}
return instance;
}
public void start(String url) {
webView.loadUrl(url);
// ...
}
// ...
}
4、避免内存泄漏
由于WebView的使用场景很多,无论在哪个地方使用WebView,都有可能引发内存泄漏问题。
下面是一些WebView内存泄漏的常见情况:
(1)在Activity销毁时未销毁WebView;
(2)没有调用WebView.destroy()方法来释放WebView的资源;
(3)绑定了Activity的上下文,导致WebView在Activity销毁后仍保持了对该Activity的引用。