4

Благодаря bug in Android 4.3, мое приложение падает при попытке загрузки некоторых веб-страниц в WebViewКак поймать это исключение в веб-браузере Android?

Трассировка стека, как это:

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) 

В моей WebView У меня есть onReceivedSslError и onReceivedError методы переопределены, но ни один из них не может поймать это исключение.

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

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

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

+0

@ClaireG: как вы можете видеть, исключение не связано ни с каким кодом, который написала SO, а скорее с известной проблемой с обработкой ssl веб-просмотров. – njzk2

+0

дублированный вопрос http://stackoverflow.com/questions/18130047/android-webview-crash-4-3 – Hariharan

+0

@Tamilan: В этом вопросе я изучаю возможность ловить такое исключение. Я не спрашиваю, почему происходит ошибка. Надеюсь, поможет. –

ответ

5

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

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. 
      } 
     }); 
    } 

} 

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

+4

+1 - Это старт, а также убедитесь, что вы сами поймали это исключение и пропустите остальные исключения для ОС. – 66CLSjY

+1

Имеет смысл, я еще не смог проверить это, но должен наградить вас щедростью, поскольку время истекает. Я буду тестировать и обновлять здесь! Одна вещь, которая по-прежнему остается необъяснимой, заключается в том, почему ошибка не может быть обнаружена на уровне активности, но может быть на уровне приложения (если это действительно работает). –

0

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

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

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