web-dev-qa-db-ja.com

Android:webview.loadUrlの使用時にURLが正常にロードされたかどうかを確認する方法

WebViewでAndroid URLをロードしようとしています。このURLのロードが正常に行われたかどうかを確認するために(インターネット接続が利用可能で、サーバーが起動していたなど))印象にありましたそのwebview.loadUrlは例外をスローしますが、間違っています! here に明示的に記述されているため、「例外はスローされません」。

では、webview.loadUrlが失敗していないかどうかを確認するにはどうすればよいですか?

13
C graphics

残念ながら、現在、WebViewでは、ページ上のすべてが正常にロードされたことを確認する簡単な方法はありません。今後のバージョンでより良いAPIが登場することを期待しています。今何ができるかを説明しましょう。

まず、メインページをロードするためにWebViewがサーバーに接続できない問題(たとえば、不正なドメイン名、I/Oエラーなど)を検出するには、_WebViewClient.onReceivedError_コールバックを次のように使用する必要があります他の人々は正しく提案します:

_public class MyWebViewClient extends WebViewClient {
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        // Make a note about the failed load.
    }
}
myWebView.setWebViewClient(new MyWebViewClient());
_

サーバー接続が成功し、メインページが取得および解析された場合、_WebView.onPageFinished_コールバックを受け取るので、これをWebViewClientサブクラスにも含める必要があります。

_public class MyWebViewClient extends WebViewClient {
    ...
    @Override
    public void onPageFinished(WebView view, String url) {
        // Make a note that the page has finished loading.
    }
    ...
}
_

ここでの注意点は、サーバーからHTTPエラー(404エラーや500エラーなど)を受け取った場合、このコールバックはとにかく呼び出され、WebViewで取得するコンテンツはサーバーエラーページだけになるということです。人々はそれを処理する方法のさまざまな方法を提案します、ここの答えを参照してください: ページが「404ページが見つかりません」である場合、Android WebViewから確認するにはどうすればよいですか? =基本的に、それは実際に「良い」ページと「エラー」ページであると予想される内容に依存しますが、残念ながら、現時点ではアプリがWebViewからHTTP応答コードを取得する方法はありません。

コールバック_WebViewClient.onPageStarted_および_WebViewClient.onProgressChanged_は、ページのロード中にプログレスバーを描画する場合にのみ役立ちます。

また、人々が通常提案する_WebViewClient.shouldOverrideUrlLoading_をオーバーライドする方法は正しくないことに注意してください。

_public class MyWebViewClient extends WebViewClient {
    ...
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url)         {  
        // !!! DO NOT DO THIS UNCONDITIONALLY !!!
        view.loadUrl(url);
        return true;
    }
    ...
}
_

ほとんどの開発者が認識していないのは、https以外のスキームを持つサブフレームに対してもコールバックが呼び出されることです。 _<iframe src='tel:1234'>_のようなものが発生した場合、WebViewは_tel:_ URLをロードする方法を認識していないため、view.loadUrl('tel:1234')が実行され、アプリにエラーページが表示されます。 。 WebViewでロードを実行する場合は、メソッドから単にfalseを返すことをお勧めします。

_public class MyWebViewClient extends WebViewClient {
    ...

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url)         {
        // Returning 'false' unconditionally is fine.
        return false;
    }
    ...
}
_

これは、shouldOverrideUrlLoadingから_WebView.loadUrl_を呼び出すべきではないという意味ではありません。避けるべき具体的なパターンは、すべてのURLに対して無条件にそうすることです。

15
Mikhail Naganov
public class AppWebViewClient extends WebViewClient {

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            // TODO Auto-generated method stub
            super.onPageStarted(view, url, favicon);
            setProgressBar(true);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            //Page load finished
            super.onPageFinished(view, url);
            setProgressBar(false);
        }
}

そしてあなたはできる

webView.setWebViewClient(new AppWebViewClient());

エラー部分については、onReceivedErrorメソッドをオーバーライドできます

@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        // TODO Auto-generated method stub
        super.onReceivedError(view, errorCode, description, failingUrl);
}
3
Manish Kumar

これが私が思いついたもので、チャームのように機能します

    Boolean failedLoading = false;
    WebView webView = view.findViewById(R.id.webView);
    webView.loadUrl("www.example.com");
    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (!failedLoading) {
                webView.setVisibility(View.VISIBLE);
                webView.setAlpha(0f);
                ObjectAnimator anim  = ObjectAnimator.ofFloat(webView, "alpha",1f);
                anim.setDuration(500);
                anim.start();
            }
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            failedLoading = true;
        }
    });

更新ボタンのようなものがあれば、関数内で上記のコードを呼び出して再試行するよりもうまくいきます:)

1
ueen