WebView採坑(一)

使用webview,你可長點心
爲什麼要寫這篇文章,其實對於webview,說簡單也簡單,說困難也困難。簡單在於如果你只是爲了簡單展示網頁或者本地html的話就簡單,困難在於你要實現的功能多了,那就會到處都是坑。所以寫webview功能的時候你要格外細心,測試的時候要認真測試。
因爲坑太多,可能有些我也記不起來(這就是不及時做筆記的下場),所以想到什麼寫什麼,也不按什麼順序或者什麼結構去列舉,就想到什麼列什麼。

1. WebViewClient的shouldOverrideUrlLoading和onReceivedError

先從簡單的開始講。
首先如果你要自定義WebViewClient的話要注意一下這兩個方法,在高版本和低版本中兩個方法傳的參數也不同。
(1)shouldOverrideUrlLoading

    // 高版本
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        return super.shouldOverrideUrlLoading(view, request);
    }

    // 低版本
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        return super.shouldOverrideUrlLoading(view, url);
    }

(2)onReceivedError

    // 高版本
    public boolean onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        return super.onReceivedError(view, request, error);
    }

    // 低版本
    public boolean onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        return super.onReceivedError(view, errorCode, description, failingUrl);
    }

還有shouldInterceptRequest方法也是等等,在高版本下使用String 沒問題,但是在低版本下是無法找到WebResourceRequest類的,也就是會報紅。
甚至不僅如此,還會出現其它的問題,所以如果要使用這兩個方法的話需要多留意一點。

2. 監聽加載完成

平時我們可能會在加載網頁的時候等進行監聽,很多監聽使用的是重寫WebViewClient的onPageFinished方法

    public void onPageFinished(WebView view, String url) {
       ......
    }

但是這個方法並不能很準確的判斷頁面加載完成,比如說webview裏面展示的首頁跳轉到另外的Url,有時候明明還是顯示着跳轉時的白屏,卻依然調用onPageFinished方法。
而我們可以使用WebChromeClient中重寫onProgressChanged方法,

    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);
        if (newProgress > 70) {
            ......
        }
    }

這個方法可以監聽進度,可以判斷如果newProgress等於100,那就是真正的頁面加載完成,但是我這是判斷大於75就算是頁面加載完成。爲什麼這樣做了,因爲首先newProgress的值不是+1的遞增,而是沒法判斷,有時候+10遞增,有時候+20遞增。而當頁面加載到70左右的時候,其實頁面已經是可以顯示出來了,然後再加載資源。但是如果我判斷100的話,有時候其實頁面是能正常顯示的,但是資源有問題,導致進度到不了100反而走了失敗的回調。認真想想,難道每次僅僅因爲一張圖片加載不出來我們就宣佈這個頁面加載失敗嗎?所以我才判斷70,我不知道這樣做是不是最好的方法,但是至少測試的時候對於大部分情景都是沒問題的。

我認爲最好的做法就是封裝起來,然後自己寫一套生命週期流程,再向外提供鉤子。至於內部的邏輯怎麼判斷,我這邊也不敢說我做的判斷就是完美的,但是用newProgress去判斷頁面加載是否完成的準確性還是比較高的。

3. SSL證書問題

這個比較好辦,如果出現這個問題,重寫這個方法,記得把super去掉

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed();
    }

4. Dialog中使用webview的坑

如果在Dialog中使用webview的過程中會因爲邏輯出現一點問題。這裏只是舉個栗子,也可能其它地方會有類似的問題,我的意思是使用webview如果不細心的話,可能會在邏輯上出現問題。
言歸正傳,說說我的問題。
當我在webview跳轉url的時候關閉Dialog,但是這樣webview依舊會做攔截的操作,即使我在關閉時設置webview等於空也沒有用,我能想到的就是寫個方法去關閉webview的全部監聽。

5. webview攔截不到鏈接

有時候你會發現webview可能攔截不到鏈接,shouldOverrideUrlLoading方法不被調用。這會有很多原因引起,百度就能收到。我這裏就只說一種情況:
有人這樣說的:第一個鏈接不是重定向的話就攔截不到
所以有的人會感覺到好像是第一個鏈接如果是加載http連接就能正常攔截到,但是加載https就攔截不到,那是因爲那些http連接會重定向到https。
雖然這個說法是這樣說,但我反倒是覺得就是webview不會攔截到第一個url,而重定向能攔截到是因爲重定向相當於跳轉url,而重定向後的就是第2個url,所以就能被攔截到。
想要鏈接到的辦法也很簡單
如果鏈接是你家的,可以自己手動搞個重定向,如果鏈接不是你家的,可以自己寫個監聽在loadurl之前。

6. onReceivedError的調用

這個也是一個細節需要注意。onReceivedError可能並非頁面加載或者跳轉url出錯時纔會調用,我之前調用支付寶的時候頁面正常加載也會調用onReceivedError方法,這樣可能就會影響到邏輯
所以需要判斷調用onReceivedError時當前加載的url是不是你加載的url

這裏暫時列舉這些吧,因爲暫時就記得這些,其實webview的坑不只這麼點,之後想起來再補充

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章