【问题标题】:How to catch this exception in Android webview?如何在 Android webview 中捕获此异常?
【发布时间】:2026-01-16 21:05:01
【问题描述】:

由于bug in Android 4.3,我的应用在尝试在 webview 中加载某些网页时崩溃

堆栈跟踪是这样的:

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)

在我的 web 视图中,我有 onReceivedSslErroronReceivedError 方法被覆盖,但它们都无法捕获此异常。

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

用 try/catch 块(如上)包围对 postUrl 的调用也不会捕获异常。

有什么方法可以捕获这个异常,以便我可以显示有意义的错误消息而不是让应用崩溃?

【问题讨论】:

  • @ClaireG :如您所见,异常与 SO 编写的任何代码无关,而是与 ssl 处理 webviews 的已知问题有关。
  • @Tamilan:在这个问题中,我正在探索捕捉这种异常的可能性。我不是在问为什么会发生错误。希望对您有所帮助。

标签: java android exception-handling android-webview android-4.3-jelly-bean


【解决方案1】:

您可能必须尝试设置全局未捕获异常处理程序。您可以通过扩展 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.
            }
        });
    }

}

只需确保您在清单中指向您的自定义应用程序类。
试一试。希望对您有所帮助。

【讨论】:

  • +1 - 这是一个开始,还要确保您单独捕获此异常并将其余异常传递给操作系统。
  • 有道理,我还不能检查出来,但由于时间不多了,所以必须奖励你。我会在这里测试并更新!仍然无法解释的一件事是为什么不能在活动级别捕获错误,但可以在应用级别捕获错误(假设这确实有效)。
【解决方案2】:

关于为什么不能在activity级别捕获异常的问题,原因是异常发生在一个新线程中,而不是在try块中。

setDefaultUncaughtExceptionHandler 有时不起作用,因为默认处理程序可能会被后面的代码覆盖。

而且您无法从 UncaughtExceptionHandler 中的异常中恢复。 您所能做的就是记录它并终止进程本身。

【讨论】: