Android - 優化WebView頁面

jopen 8年前發布 | 28K 次閱讀 Android開發 移動開發

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/

來自: http://blog.csdn.net//caroline_wendy/article/details/48469005

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!