基於騰訊x5封源庫,提升60%開發效率

目錄介紹

  • 01.前沿說明
    • 1.1 案例展現效果
    • 1.2 該庫功能和優點
    • 1.3 相關類介紹說明
  • 02.如何使用
    • 2.1 如何引入
    • 2.2 最簡單使用
    • 2.3 經常使用api
    • 2.4 使用建議
  • 03.js調用
    • 3.1 如何使用項目js調用
    • 3.2 js的調用時機分析
  • 04.問題反饋
    • 4.0.1 視頻播放寬度超過屏幕
    • 4.0.2 x5加載office資源
    • 4.0.3 WebView播放視頻問題
    • 4.0.4 沒法獲取webView的正確高度
    • 4.0.5 使用scheme協議打開連接風險
    • 4.0.6 如何處理加載錯誤
  • 05.webView優化
    • 5.0.1 視頻全屏播放按返回頁面被放大
    • 5.0.2 加快加載webView中的圖片資源
    • 5.0.3 自定義加載異常error的狀態頁面
    • 5.0.4 WebView硬件加速致使頁面渲染閃爍
    • 5.0.5 WebView加載證書錯誤
    • 5.0.6 web音頻播放銷燬後還有聲音
    • 5.0.7 DNS採用和客戶端API相同的域名
    • 5.0.8 如何設置白名單操做
  • 06.關於參考
  • 07.其餘說明介紹

01.前沿說明

  • 基於騰訊x5封源庫,提升webView開發效率,大概要節約你百分之六十的時間成本。該案例支持處理js的交互邏輯且無耦合、同時暴露進度條加載進度、能夠監聽異常error狀態、支持視頻播放而且能夠全頻、支持加載word,xls,ppt,pdf,txt等文件文檔、發短信、打電話、發郵件、打開文件操做上傳圖片、喚起原生App、x5庫爲最新版本,功能強大。

1.1 案例展現效果

  • WebView啓動過程大概分爲如下幾個階段,這裏借鑑美團的一張圖片
    • image
  • 案例效果圖展現
    • 在這裏插入圖片描述
    • 在這裏插入圖片描述
    • 在這裏插入圖片描述
    • 在這裏插入圖片描述
    • 在這裏插入圖片描述
    • 在這裏插入圖片描述
    • 在這裏插入圖片描述
    • 在這裏插入圖片描述

1.2 該庫功能和優點

  • 提升webView開發效率,大概要節約你百分之六十的時間成本,一鍵初始化操做;
  • 支持處理js的交互邏輯,方便快捷,而且無耦合;
  • 暴露進度條加載進度,結束,以及異常狀態listener給開發者;
  • 支持視頻播放,能夠切換成全頻播放視頻,可旋轉屏幕;
  • 集成了騰訊x5的WebView,最新版本,功能強大;
  • 支持打開文件的操做,好比打開相冊,而後選中圖片上傳,兼容版本(5.0)
  • 支持加載word,xls,ppt,pdf,txt等文件文檔,使用方法十分簡單

1.3 相關類介紹說明

  • BridgeHandler 接口,主要處理消息回調邏輯
  • BridgeUtil 工具類,靜態常量,以及獲取js消息的一些方法,final修飾
  • BridgeWebView 自定義WebView類,主要處理與js之間的消息
  • CallBackFunction js回調
  • DefaultHandler 默認的BridgeHandler
  • InterWebListener 接口,web的接口回調,包括常見狀態頁面切換【狀態頁面切換】,進度條變化【顯示和進度監聽】等
  • Message 自定義消息Message實體類
  • ProgressWebView 自定義帶進度條的webView
  • WebViewJavascriptBridge js橋接接口
  • X5WebChromeClient 自定義x5的WebChromeClient,處理進度監聽,title變化,以及上傳圖片,後期添加視頻處理邏輯
  • X5WebUtils 工具類,初始化騰訊x5瀏覽器webView,及調用該類init方法
  • X5WebView 可使用這個類,方便統一初始化WebSettings的一些屬性,若是不用這裏的,想單獨初始化setting屬性,也能夠直接使用BridgeWebView
  • X5WebViewClient 自定義x5的WebViewClient,若是要自定義WebViewClient必需要集成此類,必定要繼承該類,由於注入js監聽是在該類中操做的

02.如何使用

2.1 如何引入

  • 如何引用,該x5的庫已經更新到最新版本
    implementation 'cn.yc:WebViewLib:1.1.2'
    複製代碼

2.2 最簡單使用

  • 項目初始化
    X5WebUtils.init(this);
    複製代碼
  • 最普通使用,須要本身作手動設置setting相關屬性
    <BridgeWebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbarSize="3dp" />
    複製代碼
  • 也可使用X5WebView,已經作了常見的setting屬性設置
    <X5WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbarSize="3dp" />
    複製代碼
  • 若是想有帶進度的,可使用ProgressWebView
    <可使用ProgressWebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbarSize="3dp" />
    複製代碼

2.3 經常使用api

  • 關於web的接口回調,包括常見狀態頁面切換,進度條變化等監聽處理
    mWebView.getX5WebChromeClient().setWebListener(interWebListener);
    private InterWebListener interWebListener = new InterWebListener() {
        @Override
        public void hindProgressBar() {
            pb.setVisibility(View.GONE);
        }
    
        @Override
        public void showErrorView() {
            //設置自定義異常錯誤頁面
        }
    
        @Override
        public void startProgress(int newProgress) {
            pb.setProgress(newProgress);
        }
    };
    複製代碼
  • 關於視頻播放的時候,web的接口回調,主要是視頻相關回調,好比全頻,取消全頻,隱藏和現實webView
    x5WebChromeClient = x5WebView.getX5WebChromeClient();
    x5WebChromeClient.setVideoWebListener(new VideoWebListener() {
        @Override
        public void showVideoFullView() {
            //視頻全頻播放時監聽
        }
    
        @Override
        public void hindVideoFullView() {
            //隱藏全頻播放,也就是正常播放視頻
        }
    
        @Override
        public void showWebView() {
            //顯示webView
        }
    
        @Override
        public void hindWebView() {
            //隱藏webView
        }
    });
    複製代碼

2.4 使用建議

  • 優化一下相關的操做
    • 關於設置js支持的屬性
    @Override
    public void onResume() {
        super.onResume();
        if (mWebView != null) {
            mWebView.getSettings().setJavaScriptEnabled(true);
        }
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        if (mWebView != null) {
            mWebView.getSettings().setJavaScriptEnabled(false);
        }
    }
    複製代碼
    • 關於destroy銷燬邏輯
    @Override
    protected void onDestroy() {
        try {
            if (webView != null) {
                webView.stopLoading();
                webView.destroy();
                webView = null;
            }
        } catch (Exception e) {
            Log.e("X5WebViewActivity", e.getMessage());
        }
        super.onDestroy();
    }
    複製代碼

03.js調用

3.1 如何使用項目js調用

  • 代碼以下所示,下面中的jsname表明的是js這邊提供給客戶端的方法名稱
    mWebView.registerHandler("jsname", new BridgeHandler() {
        @Override
        public void handler(String data, CallBackFunction function) {
            
        }
    });
    複製代碼
  • 如何回調數據給web那邊
    function.onCallBack("回調數據");
    複製代碼

3.2 js的調用時機分析

  • onPageFinished()或者onPageStarted()方法中注入js代碼
    • 作過WebView開發,而且須要和js交互,大部分都會認爲js在WebViewClient.onPageFinished()方法中注入最合適,此時dom樹已經構建完成,頁面已經徹底展示出來。但若是作過頁面加載速度的測試,會發現WebViewClient.onPageFinished()方法一般須要等待好久纔會回調(首次加載一般超過3s),這是由於WebView須要加載完一個網頁裏主文檔和全部的資源纔會回調這個方法。
    • 能不能在WebViewClient.onPageStarted()中注入呢?答案是不肯定。通過測試,有些機型能夠,有些機型不行。在WebViewClient.onPageStarted()中注入還有一個致命的問題——這個方法可能會回調屢次,會形成js代碼的屢次注入。
    • 從7.0開始,WebView加載js方式發生了一些小改變,官方建議把js注入的時機放在頁面開始加載以後
  • WebViewClient.onProgressChanged()方法中注入js代碼
    • WebViewClient.onProgressChanged()這個方法在dom樹渲染的過程當中會回調屢次,每次都會告訴咱們當前加載的進度。
      • 在這個方法中,能夠給WebView自定義進度條,相似微信加載網頁時的那種進度條
      • 若是在此方法中注入js代碼,則須要避免重複注入,須要加強邏輯。能夠定義一個boolean值變量控制注入時機
    • 那麼有人會問,加載到多少才須要處理js注入邏輯呢?
      • 正是由於這個緣由,頁面的進度加載到80%的時候,實際上dom樹已經渲染得差很少了,代表WebView已經解析了標籤,這時候注入必定是成功的。在WebViewClient.onProgressChanged()實現js注入有幾個須要注意的地方:
      • 1 上文提到的屢次注入控制,使用了boolean值變量控制
      • 2 從新加載一個URL以前,須要重置boolean值變量,讓從新加載後的頁面再次注入js
      • 3 若是作過本地js,css等緩存,則先判斷本地是否存在,若存在則加載本地,不然加載網絡js
      • 4 注入的進度閾值能夠自由定製,理論上10%-100%都是合理的,不過建議使用了75%到90%之間能夠。

04.問題反饋

4.0.1 視頻播放寬度超過屏幕

  • 視頻播放寬度比webView設置的寬度大,超過屏幕:這個時候能夠設置ws.setLoadWithOverviewMode(false);

4.0.2 x5加載office資源

  • 關於加載word,pdf,xls等文檔文件注意事項:Tbs不支持加載網絡的文件,須要先把文件下載到本地,而後再加載出來
  • 還有一點要注意,在onDestroy方法中調用此方法mTbsReaderView.onStop(),不然第二次打開沒法瀏覽。更多能夠看FileReaderView類代碼!

4.0.3 WebView播放視頻問題

  • 一、這次的方案用到WebView,並且其中會有視頻嵌套,在默認的WebView中直接播放視頻會有問題, 並且不一樣的SDK版本狀況還不同,網上搜索了下解決方案,在此記錄下. webView.getSettings.setPluginState(PluginState.ON);webView.setWebChromeClient(new WebChromeClient());
  • 二、而後在webView的Activity配置裏面加上: android:hardwareAccelerated="true"
  • 三、以上能夠正常播放視頻了,可是webview的頁面都finish了竟然還能聽 到視頻播放的聲音, 因而又查了下發現webview的onResume方法能夠繼續播放,onPause能夠暫停播放, 可是這兩個方法都是在Added in API level 11添加的,因此須要用反射來完成。
  • 四、中止播放:在頁面的onPause方法中使用:webView.getClass().getMethod("onPause").invoke(webView, (Object[])null);
  • 五、繼續播放:在頁面的onResume方法中使用:webView.getClass().getMethod("onResume").invoke(webView,(Object[])null);這樣就能夠控制視頻的暫停和繼續播放了。

4.0.4 沒法獲取webView的正確高度

  • 偶發狀況,獲取不到webView的內容高度
    • 其中htmlString是一個HTML格式的字符串。
    WebView view = new WebView(context);
    view.loadData(htmlString, "text/html", "utf-8");
    
    view.setWebViewClient(new WebViewClient() {
        public void onPageFinished(WebView view, String url) {
         super.onPageFinished(view, url);
         Log.d("2", view.getContentheight() + "");
        }
    });
    複製代碼
    • 這是由於onPageFinished回調指的WebView已經完成從網絡讀取的字節數,這一點。在點onPageFinished被激發的頁面可能尚未被解析。
  • 第一種解決辦法:提供onPageFinished()一些延遲
    webView.setWebViewClient(new WebViewClient() {
     @Override
     public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);
      new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
        int contentHeight = webView.getContentHeight();
        int viewHeight = webView.getHeight();
       }
      }, 500);
     }
    });
    複製代碼
  • 第二種解決辦法:使用js獲取內容高度,具體能夠看這篇文章:www.jianshu.com/p/ad22b2649…

4.0.5 使用scheme協議打開連接風險

  • 常見的用法是在APP獲取到來自網頁的數據後,從新生成一個intent,而後發送給別的組件使用這些數據。好比使用Webview相關的Activity來加載一個來自網頁的url,若是此url來自url scheme中的參數,如:yc://ycbjie:8888/from?load_url=http://www.taobao.com。
    • 若是在APP中,沒有檢查獲取到的load_url的值,攻擊者能夠構造釣魚網站,誘導用戶點擊加載,就能夠盜取用戶信息。
    • 這個時候,別人非法篡改參數,因而將scheme協議改爲yc://ycbjie:8888/from?load_url=http://www.doubi.com。這個時候點擊進去便可進入釣魚連接地址。
  • 使用建議
    • APP中任何接收外部輸入數據的地方都是潛在的攻擊點,過濾檢查來自網頁的參數。
    • 不要經過網頁傳輸敏感信息,有的網站爲了引導已經登陸的用戶到APP上使用,會使用腳本動態的生成URL Scheme的參數,其中包括了用戶名、密碼或者登陸態token等敏感信息,讓用戶打開APP直接就登陸了。惡意應用也能夠註冊相同的URL Sechme來截取這些敏感信息。Android系統會讓用戶選擇使用哪一個應用打開連接,可是若是用戶不注意,就會使用惡意應用打開,致使敏感信息泄露或者其餘風險。

4.0.6 如何處理加載錯誤(Http、SSL、Resource)

  • 對於WebView加載一個網頁過程當中所產生的錯誤回調,大體有三種
    /**
     * 只有在主頁面加載出現錯誤時,纔會回調這個方法。這正是展現加載錯誤頁面最合適的方法。
     * 然而,若是無論三七二十一直接展現錯誤頁面的話,那頗有可能會誤判,給用戶形成常常加載頁面失敗的錯覺。
     * 因爲不一樣的WebView實現可能不同,因此咱們首先須要排除幾種誤判的例子:
     *      1.加載失敗的url跟WebView裏的url不是同一個url,排除;
     *      2.errorCode=-1,代表是ERROR_UNKNOWN的錯誤,爲了保證不誤判,排除
     *      3failingUrl=null&errorCode=-12,因爲錯誤的url是空而不是ERROR_BAD_URL,排除
     * @param webView                                           webView
     * @param errorCode                                         errorCode
     * @param description                                       description
     * @param failingUrl                                        failingUrl
     */
    @Override
    public void onReceivedError(WebView webView, int errorCode,
                                String description, String failingUrl) {
        super.onReceivedError(webView, errorCode, description, failingUrl);
        // -12 == EventHandle.ERROR_BAD_URL, a hide return code inside android.net.http package
        if ((failingUrl != null && !failingUrl.equals(webView.getUrl())
                && !failingUrl.equals(webView.getOriginalUrl())) /* not subresource error*/
                || (failingUrl == null && errorCode != -12) /*not bad url*/
                || errorCode == -1) { //當 errorCode = -1 且錯誤信息爲 net::ERR_CACHE_MISS
            return;
        }
        if (!TextUtils.isEmpty(failingUrl)) {
            if (failingUrl.equals(webView.getUrl())) {
                //作本身的錯誤操做,好比自定義錯誤頁面
            }
        }
    }
    
    /**
     * 只有在主頁面加載出現錯誤時,纔會回調這個方法。這正是展現加載錯誤頁面最合適的方法。
     * 然而,若是無論三七二十一直接展現錯誤頁面的話,那頗有可能會誤判,給用戶形成常常加載頁面失敗的錯覺。
     * 因爲不一樣的WebView實現可能不同,因此咱們首先須要排除幾種誤判的例子:
     *      1.加載失敗的url跟WebView裏的url不是同一個url,排除;
     *      2.errorCode=-1,代表是ERROR_UNKNOWN的錯誤,爲了保證不誤判,排除
     *      3failingUrl=null&errorCode=-12,因爲錯誤的url是空而不是ERROR_BAD_URL,排除
     * @param webView                                           webView
     * @param webResourceRequest                                webResourceRequest
     * @param webResourceError                                  webResourceError
     */
    @Override
    public void onReceivedError(WebView webView, WebResourceRequest webResourceRequest,
                                WebResourceError webResourceError) {
        super.onReceivedError(webView, webResourceRequest, webResourceError);
    }
    
    /**
     * 任何HTTP請求產生的錯誤都會回調這個方法,包括主頁面的html文檔請求,iframe、圖片等資源請求。
     * 在這個回調中,因爲混雜了不少請求,不適合用來展現加載錯誤的頁面,而適合作監控報警。
     * 當某個URL,或者某個資源收到大量報警時,說明頁面或資源可能存在問題,這時候可讓相關運營及時響應修改。
     * @param webView                                           webView
     * @param webResourceRequest                                webResourceRequest
     * @param webResourceResponse                               webResourceResponse
     */
    @Override
    public void onReceivedHttpError(WebView webView, WebResourceRequest webResourceRequest,
                                    WebResourceResponse webResourceResponse) {
        super.onReceivedHttpError(webView, webResourceRequest, webResourceResponse);
    }
    
    /**
     * 任何HTTPS請求,遇到SSL錯誤時都會回調這個方法。
     * 比較正確的作法是讓用戶選擇是否信任這個網站,這時候能夠彈出信任選擇框供用戶選擇(大部分正規瀏覽器是這麼作的)。
     * 有時候,針對本身的網站,可讓一些特定的網站,無論其證書是否存在問題,都讓用戶信任它。
     * 坑:有時候部分手機打開頁面報錯,絕招:讓本身網站的全部二級域都是可信任的。
     * @param webView                                           webView
     * @param sslErrorHandler                                   sslErrorHandler
     * @param sslError                                          sslError
     */
    @Override
    public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {
        super.onReceivedSslError(webView, sslErrorHandler, sslError);
        //判斷網站是不是可信任的,與本身網站host做比較
        if (WebViewUtils.isYCHost(webView.getUrl())) {
            //若是是本身的網站,則繼續使用SSL證書
            sslErrorHandler.proceed();
        } else {
            super.onReceivedSslError(webView, sslErrorHandler, sslError);
        }
    }
    複製代碼

05.webView優化

5.0.1 視頻全屏播放按返回頁面被放大(部分手機出現)

  • 至於緣由暫時沒有找到,解決方案以下所示
    /**
     * 當縮放改變的時候會調用該方法
     * @param view                              view
     * @param oldScale                          以前的縮放比例
     * @param newScale                          如今縮放比例
     */
    @Override
    public void onScaleChanged(WebView view, float oldScale, float newScale) {
        super.onScaleChanged(view, oldScale, newScale);
        //視頻全屏播放按返回頁面被放大的問題
        if (newScale - oldScale > 7) {
            //異常放大,縮回去。
            view.setInitialScale((int) (oldScale / newScale * 100));
        }
    }
    複製代碼

5.0.2 加載webView中的資源時,加快加載的速度優化,主要是針對圖片

  • html代碼下載到WebView後,webkit開始解析網頁各個節點,發現有外部樣式文件或者外部腳本文件時,會異步發起網絡請求下載文件,但若是在這以前也有解析到image節點,那勢必也會發起網絡請求下載相應的圖片。在網絡狀況較差的狀況下,過多的網絡請求就會形成帶寬緊張,影響到css或js文件加載完成的時間,形成頁面空白loading太久。解決的方法就是告訴WebView先不要自動加載圖片,等頁面finish後再發起圖片加載。
    //初始化的時候設置,具體代碼在X5WebView類中
    if(Build.VERSION.SDK_INT >= KITKAT) {
        //設置網頁在加載的時候暫時不加載圖片
        ws.setLoadsImagesAutomatically(true);
    } else {
        ws.setLoadsImagesAutomatically(false);
    }
    
    /**
     * 當頁面加載完成會調用該方法
     * @param view                              view
     * @param url                               url連接
     */
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        //頁面finish後再發起圖片加載
        if(!webView.getSettings().getLoadsImagesAutomatically()) {
            webView.getSettings().setLoadsImagesAutomatically(true);
        }
    }
    複製代碼

5.0.3 自定義加載異常error的狀態頁面,好比下面這些方法中可能會出現error

  • 當WebView加載頁面出錯時(通常爲404 NOT FOUND),安卓WebView會默認顯示一個出錯界面。當WebView加載出錯時,會在WebViewClient實例中的onReceivedError(),還有onReceivedTitle方法接收到錯誤
    /**
     * 請求網絡出現error
     * @param view                              view
     * @param errorCode                         錯誤🐎
     * @param description                       description
     * @param failingUrl                        失敗連接
     */
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String
            failingUrl) {
        super.onReceivedError(view, errorCode, description, failingUrl);
        if (errorCode == 404) {
            //用javascript隱藏系統定義的404頁面信息
            String data = "Page NO FOUND!";
            view.loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
        } else {
            if (webListener!=null){
                webListener.showErrorView();
            }
        }
    }
    
    // 向主機應用程序報告Web資源加載錯誤。這些錯誤一般代表沒法鏈接到服務器。
    // 值得注意的是,不一樣的是過期的版本的回調,新的版本將被稱爲任何資源(iframe,圖像等)
    // 不只爲主頁。所以,建議在回調過程當中執行最低要求的工做。
    // 6.0 以後
    @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        super.onReceivedError(view, request, error);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            X5WebUtils.log("服務器異常"+error.getDescription().toString());
        }
        //ToastUtils.showToast("服務器異常6.0以後");
        //當加載錯誤時,就讓它加載本地錯誤網頁文件
        //mWebView.loadUrl("file:///android_asset/errorpage/error.html");
        if (webListener!=null){
            webListener.showErrorView();
        }
    }
    
    /**
     * 這個方法主要是監聽標題變化操做的
     * @param view                              view
     * @param title                             標題
     */
    @Override
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);
        if (title.contains("404") || title.contains("網頁沒法打開")){
            if (webListener!=null){
                webListener.showErrorView();
            }
        } else {
            // 設置title
        }
    }
    複製代碼

5.0.4 WebView硬件加速致使頁面渲染閃爍

  • 4.0以上的系統咱們開啓硬件加速後,WebView渲染頁面更加快速,拖動也更加順滑。但有個反作用就是,當WebView視圖被總體遮住一塊,而後忽然恢復時(好比使用SlideMenu將WebView從側邊滑出來時),這個過渡期會出現白塊同時界面閃爍。解決這個問題的方法是在過渡期前將WebView的硬件加速臨時關閉,過渡期後再開啓
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }
    複製代碼
  • 5.0.5 WebView加載證書錯誤
    • webView加載一些別人的url時候,有時候會發生證書認證錯誤的狀況,這時候咱們但願可以正常的呈現頁面給用戶,咱們須要忽略證書錯誤,須要調用WebViewClient類的onReceivedSslError方法,調用handler.proceed()來忽略該證書錯誤。
    /**
     * 在加載資源時通知主機應用程序發生SSL錯誤
     * 做用:處理https請求
     * @param view                              view
     * @param handler                           handler
     * @param error                             error
     */
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        super.onReceivedSslError(view, handler, error);
        if (error!=null){
            String url = error.getUrl();
            X5WebUtils.log("onReceivedSslError----異常url----"+url);
        }
        //https忽略證書問題
        if (handler!=null){
            //表示等待證書響應
            handler.proceed();
            // handler.cancel();      //表示掛起鏈接,爲默認方式
            // handler.handleMessage(null);    //可作其餘處理
        }
    }
    複製代碼

5.0.6 web音頻播放銷燬後還有聲音

  • WebView頁面中播放了音頻,退出Activity後音頻仍然在播放,須要在Activity的onDestory()中調用
    @Override
    protected void onDestroy() {
        try {
            //有音頻播放的web頁面的銷燬邏輯
            //在關閉了Activity時,若是Webview的音樂或視頻,還在播放。就必須銷燬Webview
            //可是注意:webview調用destory時,webview仍綁定在Activity上
            //這是因爲自定義webview構建時傳入了該Activity的context對象
            //所以須要先從父容器中移除webview,而後再銷燬webview:
            if (webView != null) {
                ViewGroup parent = (ViewGroup) webView.getParent();
                if (parent != null) {
                    parent.removeView(webView);
                }
                webView.removeAllViews();
                webView.destroy();
                webView = null;
            }
        } catch (Exception e) {
            Log.e("X5WebViewActivity", e.getMessage());
        }
        super.onDestroy();
    }
    複製代碼

5.0.7 DNS採用和客戶端API相同的域名

  • 創建鏈接/服務器處理;在頁面請求的數據返回以前,主要有如下過程耗費時間。
    DNS
    connection
    服務器處理
    複製代碼
  • DNS採用和客戶端API相同的域名
    • DNS會在系統級別進行緩存,對於WebView的地址,若是使用的域名與native的API相同,則能夠直接使用緩存的DNS而不用再發起請求圖片。
    • 舉個簡單例子,客戶端請求域名主要位於api.yc.com,然而內嵌的WebView主要位於 i.yc.com。
    • 當咱們初次打開App時:客戶端首次打開都會請求api.yc.com,其DNS將會被系統緩存。然而當打開WebView的時候,因爲請求了不一樣的域名,須要從新獲取i.yc.com的IP。靜態資源同理,最好與客戶端的資源域名保持一致。

5.0.8 如何設置白名單操做

  • 客戶端內的WebView都是能夠經過客戶端的某個schema打開的,而要打開頁面的URL不少都並不寫在客戶端內,而是能夠由URL中的參數傳遞過去的。上面4.0.5 使用scheme協議打開連接風險已經說明了scheme使用的危險性,那麼如何避免這個問題了,設置運行訪問的白名單。或者當用戶打開外部連接前給用戶強烈而明顯的提示。具體操做以下所示:
    • 在onPageStarted開始加載資源的方法中,獲取加載url的host值,而後和本地保存的合法host作比較,這裏domainList是一個數組
    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
        String host = Uri.parse(url).getHost();
        LoggerUtils.i("host:" + host);
        if (!BuildConfig.IS_DEBUG) {
            if (Arrays.binarySearch(domainList, host) < 0) {
                //不在白名單內,非法網址,這個時候給用戶強烈而明顯的提示
            } else {
                //合法網址
            }
        }
    }
    複製代碼

06.關於參考

開源庫地址:github.com/yangchong21…

相關文章
相關標籤/搜索