Android WebView的使用

发布时间:2023-05-24

一、 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<String>() {
            @Override
            public void onReceiveValue(String value) {
                Log.d(TAG, "onReceiveValue: " + value);
            }
        });
    }
});

(2)JSBridge实现JavaScript与Java的互调

JSBridge是一种基于WebView的JavaScript与Java相互调用桥梁,它可以在WebView中注入一个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的引用。