Как поймать это исключение в веб-просмотре Android?

Из-за ошибки в Android 4.3 мое приложение аварийно завершает работу при попытке для загрузки определенных веб-страниц в веб-просмотре

Трассировка стека выглядит так:

09-16 14:16:48.221: E/AndroidRuntime(22487): FATAL EXCEPTION: WebViewCoreThread
09-16 14:16:48.221: E/AndroidRuntime(22487): java.lang.StringIndexOutOfBoundsException: length=0; index=-1
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.AbstractStringBuilder.indexAndLength(AbstractStringBuilder.java:212)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.AbstractStringBuilder.charAt(AbstractStringBuilder.java:206)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.StringBuffer.charAt(StringBuffer.java:346)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509NameTokenizer.nextToken(X509NameTokenizer.java:78)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509Name.<init>(X509Name.java:719)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509Name.<init>(X509Name.java:655)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509Name.<init>(X509Name.java:593)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.net.http.SslCertificate$DName.<init>(SslCertificate.java:379)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.net.http.SslCertificate.<init>(SslCertificate.java:189)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.net.http.SslCertificate.<init>(SslCertificate.java:178)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.BrowserFrame.setCertificate(BrowserFrame.java:1206)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.JWebCoreJavaBridge.nativeServiceFuncPtrQueue(Native Method)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.JWebCoreJavaBridge.handleMessage(JWebCoreJavaBridge.java:113)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.os.Looper.loop(Looper.java:137)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:814)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.Thread.run(Thread.java:841)

В моем веб-просмотре у меня есть переопределенные методы onReceivedSslError и onReceivedError, но ни один из них не может перехватить это исключение.

try{
    webview.postUrl(url, EncodingUtils.getBytes(data, "BASE64"));
}
catch(Exception e){
    System.out.println("Caught the exception!");
}

окружение вызова postUrl блоком try/catch (как указано выше) также не перехватывает исключение.

Есть ли способ перехватить это исключение, чтобы я мог отображать осмысленное сообщение об ошибке вместо того, чтобы допустить сбой приложения?


person Atul Goyal    schedule 16.09.2013    source источник
comment
@ClaireG: как вы можете видеть, исключение не связано с каким-либо кодом, написанным SO, а скорее с известной проблемой с обработкой ssl веб-просмотров.   -  person njzk2    schedule 16.09.2013
comment
повторяющийся вопрос stackoverflow.com/questions/18130047/android-webview -crash-4-3   -  person Hariharan    schedule 16.09.2013
comment
@Tamilan: В этом вопросе я изучаю возможность поймать такое исключение. Я не спрашиваю, почему происходит ошибка. Надеюсь, поможет.   -  person Atul Goyal    schedule 16.09.2013


Ответы (2)


Возможно, вам придется попробовать настроить глобальный обработчик необработанных исключений. Вы делаете это, расширяя Application и определяя там обработчик необработанных исключений. Это будет выглядеть примерно так:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, final Throwable ex) {
                // Custom code here to handle the error.
            }
        });
    }

}

Просто убедитесь, что в манифесте указан пользовательский класс Application.
Попробуйте. Надеюсь, поможет.

person SBerg413    schedule 17.10.2013
comment
+1 - это начало, а также убедитесь, что вы поймали только это исключение и передали остальные исключения в ОС. - person AjOnFire; 22.10.2013
comment
Имеет смысл, я еще не смог это проверить, но должен наградить вас наградой, так как время истекает. Я протестирую его и обновлю здесь! Одна вещь, которая до сих пор остается необъяснимой, — почему ошибка не может быть обнаружена на уровне активности, но может быть обнаружена на уровне приложения (при условии, что это действительно работает). - person Atul Goyal; 25.10.2013

Что касается вопроса, почему исключение не может быть перехвачено на уровне активности, причина в том, что исключение произошло в новом потоке, а не в блоке try.

Иногда setDefaultUncaughtExceptionHandler не работает, поскольку обработчик по умолчанию может быть перезаписан более поздним кодом.

И вы не можете восстановиться после исключения в UncaughtExceptionHandler. Все, что вы можете сделать, это зарегистрировать его и убить сам процесс.

person Jared Tsai    schedule 03.07.2015