Что делать с IOException в WebViewClient.shouldInterceptRequest()

Я пытаюсь перехватить запросы от WebView, чтобы добавить дополнительные заголовки. Я применяю WebViewClient к WebView и переопределяю shouldInterceptRequest().

В shouldInterceptRequest() я открываю соединение, добавляю заголовки, а затем возвращаю открытый поток в WebResourceResponse.

Мне не ясно, как следует обрабатывать IOException, если начальное открытие соединения не удается.

final Map<String, String> extraHeaders = getExtraHeaders(intent);
webview.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        final Uri uri = request.getUrl();

        try {
            URL           url = new URL(uri.toString());
            URLConnection con = url.openConnection();
            for (Map.Entry<String, String> h : extraHeaders.entrySet()) {
                con.addRequestProperty(h.getKey(), h.getValue());
            }
            final String contentType = con.getContentType().split(";")[0];
            final String encoding    = con.getContentEncoding();
            return new WebResourceResponse(contentType, encoding, con.getInputStream());
        } catch (IOException e) {
            // what should we do now?
            e.printStackTrace();
        }

        return super.shouldInterceptRequest(view, request);
    }
});

Я не могу оставить его неперехваченным, так как это проверенное исключение и оно не является частью подписи shouldInterceptRequest().

Я не могу обернуть его в непроверенное исключение, так как тогда WebView не поймает его и убьет приложение.

Если я поймаю и проигнорирую исключение и по умолчанию выберу метод super (который просто возвращает null), тогда WebView продолжит поведение по умолчанию и попытается отправить запрос (без моих дополнительных заголовков). Это нежелательно, так как собственная попытка подключения WebView может быть успешной, а отсутствующие заголовки вызовут больше проблем в дальнейшем.

Кажется, нет способа указать, что перехват не удался и запрос следует прервать.

Что здесь лучше всего делать?


Я попытался вернуть ответ об ошибке, но это не считается ошибкой. WebView показывает страницу с содержимым ответа (сообщение об ошибке из исключения), а обратные вызовы WebViewClient onReceivedError() или onReceivedHttpError() не вызываются.

} catch (IOException e) {
    InputStream is = new ByteArrayInputStream(e.getMessage().getBytes());
    return new WebResourceResponse("text/plain", "UTF-8", 500, "Intercept failed",
                                   Collections.<String, String>emptyMap(),
                                   is);
}

person Graham Borland    schedule 22.01.2016    source источник


Ответы (2)


Вы можете попытаться создать новый экземпляр WebResourceError, а затем вызвать WebViewClient.onReceivedError. Никогда не пробовал такое, но вот как это будет выглядеть:

} catch (final IOException e) {
    WebResourceError wre = new WebResourceError(){
        @Override
        public CharSequence getDescription (){
            return e.toString(); 
        }

        @Override
        public int getErrorCode (){
            return WebViewClient.ERROR_CONNECT;
        }
    };

    onReceivedError(view, request, wre);

    return true;
}

Также есть устаревшая версия onReceivedError, которую можно использовать, если вы не хотите или не можете создавать экземпляр WebResourceError.

person Mister Smith    schedule 29.01.2016

Сигналы о том, что произошло какое-то исключение ввода-вывода. Этот класс является общим классом исключений, создаваемых неудачными или прерванными операциями ввода-вывода.

IOException() Создает IOException с нулевым значением в качестве подробного сообщения об ошибке.

IOException(String message) Создает IOException с указанным подробным сообщением.

IOException(строковое сообщение, вызываемая причина) Создает IOException с указанным подробным сообщением и причиной.

IOException(Throwable Reason) Создает IOException с указанной причиной и подробным сообщением (cause==null ? null : case.toString()) (которое обычно содержит класс и подробное сообщение причины).

у вас есть примеры на IOException

здесь :

http://examples.javacodegeeks.com/core-java/io/ioexception/java-io-ioexception-how-to-solve-ioexception/

person omer malka    schedule 26.01.2016
comment
Это не отвечает на вопрос. Я знаю, что такое IOException. - person Graham Borland; 26.01.2016