Android - 优化WebView页面

WebView包含基础的HTML显示功能, 使用时, 需要进行多方面的优化.

(1) 常用设置

(2) 网页客户端

(3) 浏览器客户端

(4) 滚动条

(5) 获取网页内容

Code:

package me.chunyu.Pedometer.base;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

/**
 * 用于控制WebView的View
 * 由于使用WebView的类型太多,如Activity,Fragment,DialogFragment等
 * 因此将WebView的功能独立出来作为一个View
 *
 * @author MasaWong
 * @author wangchenlong
 */
@SuppressWarnings({"unused", "WeakerAccess"})
public class PedoWebView extends WebView {

    private static final String TAG = "DEBUG-WCL: " + PedoWebView.class.getSimpleName();

    @SuppressWarnings("SpellCheckingInspection")
    private static final String JS_PROCESS_TAG = "HTMLOUT"; // 用于获得HTML的内容

    // 用于获得HTML的内容, 固定格式{@link MyJavaScriptInterface}
    private static final String HTML_CONTENT = "javascript:window." + JS_PROCESS_TAG
            + ".processHTML(‘<head>‘+document.getElementsByTagName(‘html‘)[0].innerHTML+‘</head>‘);";

    private ReceivedTitleListener mReceivedTitleListener;
    private PageFinishedListener mPageFinishedListener;
    private ReceivedErrorListener mReceivedErrorListener;
    private UrlLoadingListener mUrlLoadingListener;
    private JsAlertListener mJsAlertListener;

    public PedoWebView(Context context) {
        super(context);
        if (!isInEditMode())
            init();
    }

    public PedoWebView(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
        if (!isInEditMode())
            init();
    }

    public PedoWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // 资源显示
        if (!isInEditMode())
            init();
    }

    /**
     * 构造函数,配置WebView
     */
    @SuppressLint("AddJavascriptInterface")
    public void init() {
        // clearView() is deprecated, but onBackPressed returns to about:blank
        //noinspection deprecation
        clearView();
        setWebViewClient();
        setWebChromeClient();
        setWebViewSettings();

        setHorizontalScrollBarEnabled(false);

        // 滚动条不占位
        setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

        addJavascriptInterface(new MyJavaScriptInterface(), JS_PROCESS_TAG);
    }

    /**
     * 配置WebView参数
     */
    @SuppressLint("SetJavaScriptEnabled")
    protected void setWebViewSettings() {
        WebSettings settings = getSettings();

        // User settings
        settings.setJavaScriptEnabled(true); // 允许弹窗
        settings.setLoadsImagesAutomatically(true);
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(false);

        // Technical settings
        settings.setSupportMultipleWindows(true); // 支持多窗口
        settings.setAppCacheEnabled(true);
        settings.setDatabaseEnabled(true);
        settings.setDomStorageEnabled(true);

        // 优先使用缓存
        settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
    }

    /**
     * 配置WebViewClient来处理网页加载的各种状态
     */
    protected void setWebViewClient() {
        WebViewClient webClient = new WebViewClient() {

            // 重定向会加载多次
            @Override
            public void onPageFinished(WebView view, String url) {
                getSettings().setBlockNetworkImage(false);
                if (mPageFinishedListener != null) {
                    mPageFinishedListener.overridePageFinished(view, url);
                }
                loadUrl(HTML_CONTENT); // 加载JS内容
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                if (mReceivedErrorListener != null) {
                    mReceivedErrorListener.overrideReceivedError(view, errorCode,
                            description, failingUrl);
                }
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                return mUrlLoadingListener != null &&
                        mUrlLoadingListener.overrideUrlLoading(view, url);
            }
        };
        setWebViewClient(webClient);
    }

    /**
     * 获得JS的内容
     */
    class MyJavaScriptInterface {
        @JavascriptInterface
        @SuppressWarnings("unused")
        public void processHTML(String html) {
            Log.d(TAG, "咨询医生的H5页面: " + html);
        }
    }

    /**
     * 配置WebChromeClient来处理JsAlert,用于从网页取得一些复杂的数据
     */
    protected void setWebChromeClient() {
        WebChromeClient webChromeClient = new WebChromeClient() {
            @Override
            public void onReceivedTitle(WebView view, String title) {
                if (mReceivedTitleListener != null) {
                    mReceivedTitleListener.onReceivedTitle(view, title);
                }
            }

            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                return mJsAlertListener != null &&
                        mJsAlertListener.overrideJsAlert(view, url, message, result);
            }
        };
        setWebChromeClient(webChromeClient);
    }

    /**
     * 加载Url
     *
     * @param url 需要加载的url
     */
    @Override
    public void loadUrl(String url) {
        // 把图片加载放在最后来加载渲染
        getSettings().setBlockNetworkImage(true);
        super.loadUrl(url);
    }

    public void setReceivedTitleListener(ReceivedTitleListener receivedTitleListener) {
        mReceivedTitleListener = receivedTitleListener;
    }

    public void setPageFinishedListener(PageFinishedListener pageFinishedListener) {
        mPageFinishedListener = pageFinishedListener;
    }

    public void setReceivedErrorListener(ReceivedErrorListener receivedErrorListener) {
        mReceivedErrorListener = receivedErrorListener;
    }

    public void setUrlLoadingListener(UrlLoadingListener urlLoadingListener) {
        mUrlLoadingListener = urlLoadingListener;
    }

    public void setJsAlertListener(JsAlertListener jsAlertListener) {
        mJsAlertListener = jsAlertListener;
    }

    public interface ReceivedTitleListener {
        void onReceivedTitle(WebView view, String title);
    }

    public interface PageFinishedListener {
        void overridePageFinished(WebView view, String url);
    }

    public interface ReceivedErrorListener {
        void overrideReceivedError(WebView view, int errorCode, String description,
                                   String failingUrl);
    }

    public interface UrlLoadingListener {
        boolean overrideUrlLoading(WebView view, String url);
    }

    public interface JsAlertListener {
        boolean overrideJsAlert(WebView view, String url, String message, JsResult result);
    }
}

参考: http://www.pedant.cn/2014/09/10/webview-optimize-points/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-09-28 23:39:39

Android - 优化WebView页面的相关文章

android解决webview,页面关闭之后,视频或者音频还在播放的问题

方法1: 调用 webView.loadUrl("about:blank"); 这个方法会 销毁所有的video和audio 包括js的所有正在运行的function 方法2: @Override public void onPause() { super.onPause(); myWebView.onPause(); myWebView.pauseTimers(); } @Override public void onResume() { super.onResume(); myWe

Android WebView页面加载优化

目前webapp越来越多,体验也越来越好,为了能够更好的使用WebView展示出流畅的的页面,可以从以下几点做优化: WebView缓存 资源文件本地存储 减少耗时操作 客户端UI优化 可能有人会说了,为什么不做成native的呢,这样就不用那么的麻烦了.如果我需要加载的内容都是静态的,当然做成native的是最好的,为什么我们要使用WebView呢,因为它可以加载一些容易改变的内容,同时也方便制作多平台应用. WebView可以优化的哪些地方呢? WebView缓存 开启WebView的缓存功

[Android] 在WebView的页面中直接使用res中的图片

WebView页面中使用res中图片的方法: <img id="img" src="file:///android_res/drawable/ic_launcher.png" /> 附测试页面: <!doctype html> <html> <head> <meta charset="utf-8"> <script type="text/javascript"&

android重写webview长按时选择文字然后点击搜索按钮的事件,默认是chrome接受点击事件,现在跳转到360搜索页面

用这个FindWebView替换默认使用的webview就可以了,重写SelectedText 类里地 show方法 string data就是获取到的选中的文字 import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.os.Build; imp

Android使用WebView开发常见的坑

原文链接:http://mp.weixin.qq.com/s?__biz=MzAwODE1NTI2MQ==&tempkey=uP3a%2BOgIN7vPbLfJp3BTCl2KabYi1%2FfBUQEkkQD7ixoNgGn4JfrR81AwdwsBof%2FhsiCe4%2B9o0KJQ6lv%2B32pSyH46EQAIwJ5i%2BxxED%2BjrIpwHyFCFbDUibPnNlrZDxQAc4JV34qtCRBPLX6fF3qjtjQ%3D%3D&chksm=1b727810

测量webView页面性能技术方案

测量webView页面性能(使用UiAutomator和性能监控工具) 背景: 俺双11会场测试的总指挥想要确认,在猫客的webview中填多少坑位合适,所以进行了如下操作并获取性能: 1,进入webview页面滑动到底部,然后再快速回到顶部, 2,点击顶部的banner进入下级页面, 3,页面深度3层,即重复1,2该操作3次. 采用的技术 需求拆分为2部分,webview控制脚本和性能监控. 脚本 UiAutomator 因为猫客的自动化采用UiAutomator实现,已经提供了很多封装方法,

Android一组WebView的随机,顺序,倒序加载

写了个应用,实现了一组WebView的顺序,倒序,和随机加载.之中使用了延时,为什么要使用呢?请看下图: package com.zms.csdngo; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiManager; i

Android的WebView通过JS调用java代码

做项目时候会遇到我们用WebView 打开一个web,希望这个web可以调用自己的一些方法,比如我们在进一个web页面,然后当我们点击web上的某个按钮时,希望能判断当前手机端是否已经登录,如果未登录,那么就会跳转到登录页面(登陆页面是另一个Activity).这个时候,一个简单的做法就是在按钮动作事件的js上调用java的方法,从而起到判断是否登录,并决定是否跳转到另一个页面. Google的WebView为我们提供了 addJavascriptInterface(Object obj, St

Android调用WebView

mWebView.setWebViewClient(new WebViewClient(){                           public boolean shouldOverrideUrlLoading(WebView view, String url) {                               view.loadUrl(url);                               return true;