围绕SetSpan的Xamarin内部Android崩溃

时间:2017-02-03 23:32:37

标签: xamarin xamarin.android

我们有一个Xamarin Android应用程序,有时会遇到以下崩溃:

d Java.Lang.RuntimeExceptionsetSpan (13 ... 31) ends beyond length 18
Raw

  --- End of managed Java.Lang.RuntimeException stack trace ---
java.lang.IndexOutOfBoundsException: setSpan (13 ... 31) ends beyond length 18
    at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1016)
    at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:592)
    at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
    at android.widget.TextView.setSpan_internal(TextView.java:8753)
    at android.widget.Editor$SuggestionsPopupWindow.onItemClick(Editor.java:2789)
    at android.widget.AdapterView.performItemClick(AdapterView.java:299)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
    at android.widget.AbsListView$3.run(AbsListView.java:3638)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5050)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
    at dalvik.system.NativeStart.main(Native Method)

经过一番调查后,我们确定了导致此次崩溃的原因,以及其他人(使用普通的Android,而不是Xamarin,已经解决了这个问题):

https://code.google.com/p/android/issues/detail?id=82788

解决方案是扩展EditText并覆盖两个受保护的方法:

protected void setSpan_internal(Object span, int start, int end, int flags) {
    final int textLength = getText().length();
    ((Editable) getText()).setSpan(span, start, Math.min(end, textLength),  flags);
}

protected void setCursorPosition_internal(int start, int end) {
    final int textLength = getText().length();
    Selection.setSelection(((Editable) getText()), Math.min(start, textLength), Math.min(end, textLength));
}

很棒,一个简单的解决方案。当然,除了Xamarin在包装它们时似乎使这些方法变得私密。在EditText(或TextView)的Xamarin实现中无法访问它们。

那么有没有人对如何在Xamarin中解决这个问题有任何想法?我相信我可以创建一个执行此修复程序的自定义Android DLL,然后将其包装在Xamarin绑定中。但我希望别人有一个更简单的想法。

1 个答案:

答案 0 :(得分:0)

所以我最终创建了一个自定义Android库,它有一个扩展EditText的自定义类并修复了两个方法(原始问题中提到的解决方案)。

然后我将它包装在Xamarin绑定中,它解决了这个问题。

我还可以确认这只发生在运行4.4.2的Zebra TC70设备上。非常具体和模糊。