【问题标题】:IndexOutOfBoundsException in WebViewWebView 中的 IndexOutOfBoundsException
【发布时间】:2012-12-23 23:03:02
【问题描述】:

我最近收到了我的一位用户关于运行 Android 4.1.1 的 ASUS Transformer Pad TF700T 的崩溃报告。我看到过类似的 TextViews 崩溃报告,通常会重新添加到一些自定义代码中。这个是针对 WebView 的,我写的似乎没有任何与此崩溃直接相关的代码。

我没有更多信息,但是当用户单击 web 视图中显示的编辑框时可能会发生这种情况(我知道 web 视图中显示的页面的 URL 和内容)。我不知道如何处理这个......

java.lang.IndexOutOfBoundsException: setSpan (-4 ... -4) starts before 0
at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1021)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:592)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
at android.text.Selection.setSelection(Selection.java:76)
at android.view.inputmethod.BaseInputConnection.setSelection(BaseInputConnection.java:497)
at android.webkit.WebViewClassic$WebViewInputConnection.setSelection(WebViewClassic.java:482)
at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:288)
at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

    标签: android android-webview indexoutofboundsexception


    【解决方案1】:

    由于某种原因,似乎尝试进行具有负起始索引的文本选择。至少,stracktrace 是这么告诉你的。:

    Selection 中的第 67 行:

    text.setSpan(SELECTION_START, start, start, Spanned.SPAN_POINT_POINT|Spanned.SPAN_INTERMEDIATE);
    

    显然start 的值为-4。它作为参数传入,如果您跟踪回溯,该值将从DO_SET_SELECTION 消息中解析出来。

    我猜如果在选择过程中WebView 中选择的文本发生更改,但没有任何难以确认的额外细节,则可能会发生错误。

    有趣的是,BaseInputConnection.setSelection(int, int) 确实包含一个有趣的代码注释,使我之前的猜测更加合理:

    /**
     * The default implementation changes the selection position in the
     * current editable text.
     */
    public boolean setSelection(int start, int end) {
        if (DEBUG) Log.v(TAG, "setSelection " + start + ", " + end);
        final Editable content = getEditable();
        if (content == null) return false;
        int len = content.length();
        if (start > len || end > len) {
            // If the given selection is out of bounds, just ignore it.
            // Most likely the text was changed out from under the IME,
            // the the IME is going to have to update all of its state
            // anyway.
            return true;
        }
        if (start == end && MetaKeyKeyListener.getMetaState(content,
                MetaKeyKeyListener.META_SELECTING) != 0) {
            // If we are in selection mode, then we want to extend the
            // selection instead of replacing it.
            Selection.extendSelection(content, start);
        } else {
            Selection.setSelection(content, start, end);
        }
        return true;
    }
    

    有一个越界检查,但仅限于上限,而不是下限。添加对start < 0 || end < 0 的检查可能会阻止IndexOutOfBoundsException 被抛出,如您的stracktrace 中所示。不幸的是,这可能对您没有帮助,因为您不太可能能够从WebView 控制事件流...

    【讨论】:

    • 不错的分析。谢谢!问题是:我应该将其视为 WebView 中的错误吗?为什么即使文本发生更改,DO_SET_SELECTION 也会包含负起始值?
    • 该问题已在 Android 5.0 中修复。新条件为:start > len || end > len || start < 0 || end < 0
    猜你喜欢
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2016-03-17
    • 1970-01-01
    相关资源
    最近更新 更多