Android中webview在使用過程中會遇到的一些問題

本文中我們將介紹一下Android中webview在使用過程中會遇到的一些問題。這些問題主要是webview在使用過程中我已經趟過的坑,希望通過這篇文章的介紹能夠幫助大家更好的使用webview。

下面是本文主要介紹的一些知識點,後續使用過程中可能會有更新。

  • webview的性能優化

  • webview注入cookie信息

  • webview退出activity異常

  • webview中native與js交互

  • webview下載文件

  • 騰訊X5瀏覽服務

最近App中相當一部分的頁面內容使用的是webview。而使用webview加載頁面一個需要注意的地方就是性能,所以最近也研究了一下webview的性能優化問題。

webview的性能問題

在講解webview的性能問題之前,我們先來了解一下Android webview的緩存機制。

  • Android WebView緩存機制

WebView中存在着兩種緩存:網頁數據緩存(網頁數據,url等)、H5緩存(H5代碼緩存數據)

不同的緩存數據會保存在不同的文件目錄下,這裏引用一下其他blog的說法:

當我們加載Html時候,會在我們data/應用package下生成database與cache兩個文件夾: 
我們請求的Url記錄是保存在webviewCache.db裏,而url的內容是保存在webviewCache文件夾下。 
這裏寫圖片描述

webview中也是可以設置緩存是否可用的,一般是通過WebSettings對象設置,下面我們就來看一下WebSettings對象的使用。

  • Android中webview組件有幾個重要的方法
<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
webSettings.setLoadWithOverviewMode(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
webSettings.setAllowFileAccess(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
webSettings.setUseWideViewPort(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
webSettings.setDatabaseEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
webSettings.setAppCacheEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
webSettings.setBlockNetworkImage(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 設置WebView的Client</span>
mWebView.setWebViewClient(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> MWebViewClient(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 設置可現實js的alert彈窗</span>
mWebView.setWebChromeClient(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> WebChromeClient());</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

可以看到我們可以使用WebSettings對象設置緩存是否可用,緩存DB是否可用等。我們需要首先確保這裏設置了緩存可用,纔可以繼續設置使用何種緩存策略。

下面我們來看一下webview的五種緩存模式: 
LOAD_CACHE_ONLY: 不使用網絡,只讀取本地緩存數據 
LOAD_DEFAULT: 根據cache-control決定是否從網絡上取數據。 
LOAD_CACHE_NORMAL: API level 17中已經廢棄, 從API level 11開始作用同LOAD_DEFAULT模式 
LOAD_NO_CACHE: 不使用緩存,只從網絡獲取數據. 
LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據。

  • 幾種緩存方式的實現

(1)使用LOAD_CACHE_ELSE_NETWORK緩存模式,這樣需要在APP退出的時候清除webview緩存,但是這樣做有一個弊端就是如果當前App已經是打開狀態,網頁內容有更新的話不會看到;

(2)使用LOAD_DEFAULT這種緩存方式,數據從緩存中獲取還是從網絡中獲取根據H5頁面的參數判斷,這樣做的好處是可以動態的處理更新內容;

  • 設置緩存
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mWebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSettings</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setJavaScriptEnabled</span>(true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>
     mWebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSettings</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setRenderPriority</span>(RenderPriority<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.HIGH</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;  mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  //設置 緩存模式 </span>
        // 開啓 DOM storage API 功能 
        mWebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSettings</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setDomStorageEnabled</span>(true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>
        //開啓 database storage API 功能 
        mWebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSettings</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setDatabaseEnabled</span>(true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;  </span>
        String cacheDirPath = getFilesDir()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAbsolutePath</span>()+APP_CACAHE_DIRNAME<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>
//      String cacheDirPath = getCacheDir()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAbsolutePath</span>()+Constant<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.APP</span>_DB_DIRNAME<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>
        Log<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.i</span>(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"cacheDirPath="</span>+cacheDirPath)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>
        //設置數據庫緩存路徑 
        mWebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSettings</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setDatabasePath</span>(cacheDirPath)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>
        //設置  Application Caches 緩存目錄 
        mWebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSettings</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setAppCachePath</span>(cacheDirPath)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>
        //開啓 Application Caches 功能 
        mWebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSettings</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setAppCacheEnabled</span>(true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>
  • 退出App時清除緩存
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//清理Webview緩存數據庫 </span>
        try { 
            deleteDatabase(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"webview.db"</span>);  
            deleteDatabase(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"webviewCache.db"</span>); 
        } catch (Exception e) { 
            e<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>printStackTrace(); 
        } 

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//WebView 緩存文件 </span>
        File appCacheDir <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> File(getFilesDir()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getAbsolutePath()<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span>APP_CACAHE_DIRNAME); 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Log</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>e(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">TAG</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"appCacheDir path="</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span>appCacheDir<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getAbsolutePath()); 

        File webviewCacheDir <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> File(getCacheDir()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getAbsolutePath()<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/webviewCache"</span>); 
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Log</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>e(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">TAG</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"webviewCacheDir path="</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span>webviewCacheDir<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getAbsolutePath()); 

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//刪除webview 緩存目錄 </span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(webviewCacheDir<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>exists()){ 
            deleteFile(webviewCacheDir); 
        } 
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//刪除webview 緩存 緩存目錄 </span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(appCacheDir<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>exists()){ 
            deleteFile(appCacheDir); 
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>
  • 其他的緩存策略

網頁在加載的時候暫時不加載圖片,當所有的HTML標籤加載完成時在加載圖片具體的做法如下初始化webview的時候設置不加載圖片

<code class="hljs bash has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">webSettings.setBlockNetworkImage(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

然後在html標籤加載完成之後在加載圖片內容:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onPageFinished</span>(WebView view, String url) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onPageFinished(view, url);
        mWebView.getSettings().setBlockNetworkImage(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);   
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

O(∩_∩)O哈哈~,這樣做的好處就是可以給人的感覺網頁加載速度很快…

  • 將網頁內容中需要的js,css引用文件保存在App本地

加載網頁內容時,在加載完成html後替換頁面內容引用的地址改爲本地的資源文件地址,這樣可以直接加載本地的資源文件加快資源的訪問速度,目前主流的新聞客戶端訪問webview時多采用這種方式。

好吧,講解完了webview的性能優化問題之後我們在講解一下如何在H5頁面種入Cookie信息。

H5頁面種入Cookie問題

app中存在webview控件,既可以通過Native與js代碼交互的方式實現信息的交互也可以通過cookie的方式與實現Native與H5端的交互,查詢的好多資料各種各樣的實現方式都有,最終不斷嘗試基本實現了需求,現說明一下最終的實現方式;

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 客戶端將cookie種入H5頁面中,H5頁面可以通過js代碼實現對native種入cookie信息的讀取操作
     */</span>
    public static void synCookies(Context context, String url, String cookie) {
        CookieSyncManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.createInstance</span>(context)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        CookieManager cookieManager = CookieManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getInstance</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        cookieManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setAcceptCookie</span>(true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

        Uri uri = null<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        String domain = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        try {
            uri = Uri<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parse</span>(URLDecoder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.decode</span>(url, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"utf-8"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            domain = uri<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getHost</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        } catch (UnsupportedEncodingException e) {
            e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        }
        String cookieStr = cookieManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getCookie</span>(url)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        // 判斷token是否發生變化,發生變化的話則更新cookie
        L<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.i</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"cookieEquce:"</span> + cookie<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.equals</span>(H5Constant<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TOKEN</span> + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"="</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        if (!TextUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isEmpty</span>(cookieStr) && cookieStr<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.contains</span>(cookie) && !cookie<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.equals</span>(H5Constant<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TOKEN</span> + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"="</span>)) {
            return<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        }
        // 更新domain(不再從UserInfo中獲取,更改爲從UrlInfo中獲取)
        if (!TextUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isEmpty</span>(URLConfig<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getUrlInfo</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getB</span>4Domain())) {
            domain = URLConfig<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getUrlInfo</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getB</span>4Domain()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        }
        List<String> uaList = SysConfig<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSystemUa</span>(context)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        String md = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">";domain="</span> + domain<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        // 添加經緯度信息到Cookie中
        cookieManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCookie</span>(url, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"lat="</span> + Config<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lat</span> + md)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        cookieManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCookie</span>(url, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"lng="</span> + Config<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lng</span> + md)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        cookieManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCookie</span>(url, cookie + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">";"</span> + md)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        if (uaList != null && uaList<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.size</span>() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
            for (String coo : uaList) {
                cookieManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCookie</span>(url, coo + md)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            }
        }

        CookieSyncManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getInstance</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.sync</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul>

其中CookieManager是cookie的管理對象,主要實現對網頁cookie的注入與清除等工作。注入字符串的形式是:key=value;domain=url的形式(其中url爲需要注入cookie的url鏈接地址)

那麼如何移除cookie呢?

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 移除cookie
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">removeCookies</span>(Context context) {
        CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeSessionCookie();

        CookieSyncManager.getInstance().sync();
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

一般情況下都是在打開H5頁面的時候種入Cookie信息,然後在離開H5頁面的時候清除cookie信息。當然了通過cookie實現native與js的交互只是實現信息交互的一種方式,我們還可以通過js與Java代碼相互調用的方式實現相互交互,文章的後面會有介紹。

而下面我們再來講解一下activity退出時webview報錯的問題。

Activity退出時webview報錯的問題

前段時間在調試代碼的時候,有一段關於webview的代碼,即退出Fragment的時候清除webview,這時候在其他手機上是沒有問題的,但是在三星Grand2中報錯,而其報錯信息是:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-label" style="box-sizing: border-box;">java.lang.Throwable:</span> Error: WebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.destroy</span>() called while still attached!
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webkit</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.WebViewClassic</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.destroy</span>(WebViewClassic<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4173</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webkit</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.WebView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.destroy</span>(WebView<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">707</span>)
at <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.youyou</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.uuelectric</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.renter</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.UI</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.web</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.H</span>5Fragment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.onDestroyView</span>(H5Fragment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">202</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>4<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Fragment</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.performDestroyView</span>(Fragment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2167</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>4<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FragmentManagerImpl</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveToState</span>(FragmentManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1141</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>4<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FragmentManagerImpl</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveToState</span>(FragmentManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1248</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>4<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FragmentManagerImpl</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveToState</span>(FragmentManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1230</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>4<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FragmentManagerImpl</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.dispatchDestroy</span>(FragmentManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2079</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>4<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FragmentController</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.dispatchDestroy</span>(FragmentController<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">235</span>)
 at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>4<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FragmentActivity</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.onDestroy</span>(FragmentActivity<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">326</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.support</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.v</span>7<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.AppCompatActivity</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.onDestroy</span>(AppCompatActivity<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">161</span>)
at <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.youyou</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.uuelectric</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.renter</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.UI</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.base</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.BaseActivity</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.onDestroy</span>(BaseActivity<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">136</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Activity</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.performDestroy</span>(Activity<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5543</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Instrumentation</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.callActivityOnDestroy</span>(Instrumentation<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1134</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ActivityThread</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.performDestroyActivity</span>(ActivityThread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3637</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ActivityThread</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.handleDestroyActivity</span>(ActivityThread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3672</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ActivityThread</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.access</span>$1300(ActivityThread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">168</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ActivityThread</span>$H<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.handleMessage</span>(ActivityThread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1382</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.os</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Handler</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.dispatchMessage</span>(Handler<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">99</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.os</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Looper</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.loop</span>(Looper<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">176</span>)
at Android<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.app</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ActivityThread</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.main</span>(ActivityThread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5493</span>)
at java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lang</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reflect</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Method</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.invokeNative</span>(Native Method)
at java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lang</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reflect</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Method</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.invoke</span>(Method<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">525</span>)
at <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Android</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.internal</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.os</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ZygoteInit</span>$MethodAndArgsCaller<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.run</span>(ZygoteInit<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1225</span>)
at <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Android</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.internal</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.os</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ZygoteInit</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.main</span>(ZygoteInit<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.java</span>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1041</span>)
at dalvik<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.system</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.NativeStart</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.main</span>(Native Method)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>

程序也沒有異常退出之類的動作,清除webview的代碼是這樣寫的:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDestroyView</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDestroyView();
        mWebView.removeAllViews();
        mWebView.destroy();
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

這個錯誤大概的意思是:當你結束webview的時候,webview還依附在其父控件之下,應當在調用webview.destory()方法之前接觸他們之間的依附關係,那麼既然錯誤提示信息已經很明顯了,我們就根據錯誤信息嘗試着首先執行webview父控件的清除工作,然後在執行webview控件的清除操作,所以代碼中應該這樣實現:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDestroyView</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDestroyView();
        swipeRefreshLayout.removeView(mWebView);
        mWebView.removeAllViews();
        mWebView.destroy();
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

這樣經過修改之後特定機型上關於webview的錯誤就不在了。

webview中實現Native與js相互調用

上面我們介紹的通過cookie實現Android native與H5的信息交互只是一種方式,我們也可以通過java代碼與js代碼直接相互調用的方式實現Android native與H5信息的相互,這裏簡單的介紹一下使用方式

  • native代碼調用H5的js代碼

(1)在H5頁面中添加一個js函數

<code class="hljs xml has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"text/javascript"</span>></span><span class="javascript" style="box-sizing: border-box;">
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">uu_click</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(clicked_id)</span> {</span>
    alert(clicked_id);
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

(2)在Native中通過java代碼調用 
若這時候H5頁面已經被加載到webview中,則可以通過java代碼直接調用js函數:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">h5Fragment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mWebView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.loadUrl</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"javascript:uu_click"</span> + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"('"</span> + clickId + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"')"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

是的,沒錯就是這麼簡單,這樣就實現了java代碼對js代碼的調用,但是需要指出的是這裏無法調用含有返回值的js函數,這裏也算是小小的問題吧,但是話說回來,一般也沒有這種需要調用js代碼並獲得返回值的場景吧。

  • js代碼調用java函數

(1)首先在java端編寫能夠被js代碼調用的java函數

  • native方法的實現
<code class="hljs r has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">/**
 * 自定義實現的native函數,可被js代碼調用
 */
class JsInteration {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
    @JavascriptInterface
        public void toastMessage(String message) {
            Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
        }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

(2)在native中注入本地方法,供js調用;

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mWebView.addJavascriptInterface(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> JsInteration(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"control"</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

(3)在js代碼中調用java代碼:

<code class="hljs lua has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">reply_click</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(clicked_id {
    window.control.toastMessage(clicked_id)</span></span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

以上就是webview中使用js代碼與java代碼相互調用的簡單例子。

webview下載文件

在使用webview開發中還遇到一個問題,app中webview中存在下載鏈接,但是在手機瀏覽器中點擊下載是沒有問題的,在webview中怎麼都不好使。查詢了好久,原來是因爲WebView默認沒有開啓文件下載的功能,如果要實現文件下載的功能,需要設置WebView的DownloadListener,通過實現自己的DownloadListener來實現文件的下載。

  • 設置webview的setDownloadListener方法
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">mWebView.setDownloadListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DownloadListener() {
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDownloadStart</span>(String url, String userAgent, String contentDisposition, String mimetype, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> contentLength) {
                L.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"tag"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"this is a message!!!"</span>);
            }
        });</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
  • 重寫onDownloadStart回調方法,實現下載文件的邏輯

比如在瀏覽器中實現下載:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>  
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDownloadStart</span>(String url, String userAgent, String contentDisposition, String mimetype,  
                                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> contentLength) {  
            Uri uri = Uri.parse(url);  
            Intent intent = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Intent(Intent.ACTION_VIEW, uri);  
            startActivity(intent);  
        }  </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

這樣我們的webview中如果包含了下載鏈接就可以通過打開瀏覽器的方式實現下載了。

注:個人感覺webview沒有默認實現下載鏈接的功能更多的可能是考慮權限,安全方面的問題。

騰訊X5瀏覽服務

由於不同的手機版本問題,各個廠商的定製化操作,webview在不同的手機上表現有很大的不同,所以webview的適配工作在Android機上顯得比較重要,這裏我們就簡單的介紹一下騰訊的X5瀏覽服務,其相當於Android上webview的第三方框架。

這裏先暫時看一下騰訊X5服務的官方介紹,其官網是:騰訊瀏覽服務,然後我們看一下X5瀏覽服務官網對其的描述。

騰訊瀏覽服務由QQ瀏覽器團隊出品,致力於優化移動端webview體驗的整套解決方案,使用QQ瀏覽器X5內核SDK和X5雲端服務,解決移動端webview使用過程中出現的一切問題,優化用戶的瀏覽體驗,同時騰訊還將持續提供後續的更新和優化,爲開發者提供最新最優秀的功能和服務。

X5SDK是通過調用微信/手機QQ/空間的X5內核,解決系統webview兼容性差、加載速度慢、功能缺陷等問題,開發接入便捷,大小隻有253K,僅需幾行代碼,即可解決一切令開發者們頭疼的問題,爲用戶提供最優秀的瀏覽體驗。 
同時,QQ瀏覽器團隊還將持續更新和優化X5內核,持續優化功能,並保證兼容各種web新特性。

  • 騰訊X5瀏覽服務的優勢:

1) 速度快:相比系統webView的網頁加載速度有近30%的提升。 
2) 省流量:雲端優化技術使流量節省20% 
3) 更安全:24小時安全問題解決機制 
4) 更穩定:經過億級用戶的使用考驗,CRASH率0.15% 
5) 集成強大的視頻播放器,支持各種視頻格式直接打開 
6) 適屏排版、字體設置等瀏覽增強功能的提供 
7) HTML5更完整支持。 
8) 無系統內核的碎片化問題,更少的兼容性問題

那麼現在那些App具體接入了X5服務了呢? 

發佈了26 篇原創文章 · 獲贊 13 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章