Android中使用SpannableStringBuilder与TextView时偶发setSpan越界崩溃问题求助
Android中使用SpannableStringBuilder与TextView时偶发setSpan越界崩溃问题求助
我在Android开发中使用SpannableStringBuilder和TextView时遇到了偶发的崩溃问题,错误提示为java.lang.IndexOutOfBoundsException: setSpan (0 ... -1) has end before start。这个崩溃不是每次都会出现,但偶尔触发,实在让人头疼。
具体场景是:在Fragment中,我通过LiveData接收Service里更新的SpannableStringBuilder对象,用来更新界面上的TextView。下面是相关的Java代码、Logcat日志以及变量输出,希望能得到大佬们的帮助找到修复方法。我已经在Google Issue Tracker和Stack Overflow上查找过,没找到完全匹配的错误信息,类似的问题也解决不了我的情况。
相关代码
Fragment代码
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ... textViewLog = (TextView)view.findViewById(R.id.textview_log); scrollview = ((NestedScrollView) view.findViewById(R.id.scrollview)); // Create the observer which updates the UI. final Observer<SpannableStringBuilder> ETAObserver = new Observer<SpannableStringBuilder>() { @Override public void onChanged(@Nullable final SpannableStringBuilder spannableLog) { // Update the UI, in this case, a TextView. getActivity().runOnUiThread(new Runnable() { @Override public void run() { String textViewLogStringBeforeUpdate = null; if (BuildConfig.IS_TESTING.get()) { // For Debug purposes: to try to understand this rare exception // java.lang.IndexOutOfBoundsException: setSpan (0 ... -1) has end before start textViewLogStringBeforeUpdate = textViewLog.getText().toString(); } try { textViewLog.setText(spannableLog); } catch (IndexOutOfBoundsException e) { String msg = e.getMessage(); if (msg != null && msg.startsWith("setSpan")) { e.printStackTrace(); Log.e("ETATest", "Crash with message: " + msg); Log.v("ETATest", "textViewLog Before: " + textViewLogStringBeforeUpdate); Log.v("ETATest", "spannableLog: " + spannableLog); Log.v("ETATest", "textViewLog After: " + textViewLog.getText()); } else { throw e; } } // Stuff that updates the UI scrollview.post(new Runnable() { @Override public void run() { scrollview.fullScroll(ScrollView.FOCUS_DOWN); } }); } }); } }; // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer. AddThumbsLogLiveData.get().observe(getViewLifecycleOwner(), ETAObserver); }
LogLiveData代码
public class AddThumbsLogLiveData extends LiveData<SpannableStringBuilder> { private static AddThumbsLogLiveData sInstance; private final static SpannableStringBuilder log = new SpannableStringBuilder(""); @MainThread public static AddThumbsLogLiveData get() { if (sInstance == null) { sInstance = new AddThumbsLogLiveData(); } return sInstance; } private AddThumbsLogLiveData() { } public void appendLog(String text) { if (enableLog) Log.i(TAG, text); log.append(text); postValue(log); } public void appendLog(Spanned text) { if (enableLog) Log.i(TAG, text.toString()); log.append(text); postValue(log); } public void clear() { log.clear(); } }
崩溃日志及变量输出
03-10 10:22:36.446 16047 16413 I ETALog : Processing /storage/emulated/0/DCIM/test_standard_addThumbsSettingsDefaultTwoRuns 03-10 10:22:36.455 16047 16413 I ETALog : Checking permissions… 03-10 10:22:36.458 16047 16413 I ETALog : Successful 03-10 10:22:36.460 16047 16047 W System.err: java.lang.IndexOutOfBoundsException: setSpan (0 ... -1) has end before start 03-10 10:22:36.476 16047 16047 W System.err: at android.text.SpannableStringInternal.checkRange(SpannableStringInternal.java:485) 03-10 10:22:36.476 16047 16047 W System.err: at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:199) 03-10 10:22:36.476 16047 16047 W System.err: at android.text.SpannableStringInternal.copySpansFromSpanned(SpannableStringInternal.java:87) 03-10 10:22:36.476 16047 16047 W System.err: at android.text.SpannableStringInternal.<init>(SpannableStringInternal.java:48) 03-10 10:22:36.476 16047 16047 W System.err: at android.text.SpannedString.<init>(SpannedString.java:35) 03-10 10:22:36.476 16047 16047 W System.err: at android.text.SpannedString.<init>(SpannedString.java:44) 03-10 10:22:36.476 16047 16047 W System.err: at android.text.TextUtils.stringOrSpannedString(TextUtils.java:532) 03-10 10:22:36.476 16047 16047 W System.err: at android.widget.TextView.setText(TextView.java:6318) 03-10 10:22:36.476 16047 16047 W System.err: at android.widget.TextView.setText(TextView.java:6227) 03-10 10:22:36.476 16047 16047 W System.err: at android.widget.TextView.setText(TextView.java:6179) 03-10 10:22:36.476 16047 16047 W System.err: at com.exifthumbnailadder.app.AddThumbsFragment$4$1.run(AddThumbsFragment.java:162) 03-10 10:22:36.476 16047 16047 W System.err: at android.app.Activity.runOnUiThread(Activity.java:7133) 03-10 10:22:36.476 16047 16047 W System.err: at com.exifthumbnailadder.app.AddThumbsFragment$4.onChanged(AddThumbsFragment.java:152) 03-10 10:22:36.476 16047 16047 W System.err: at com.exifthumbnailadder.app.AddThumbsFragment$4.onChanged(AddThumbsFragment.java:148) 03-10 10:22:36.476 16047 16047 W System.err: at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133) 03-10 10:22:36.476 16047 16047 W System.err: at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151) 03-10 10:22:36.476 16047 16047 W System.err: at androidx.lifecycle.LiveData.setValue(LiveData.java:309) 03-10 10:22:36.476 16047 16047 W System.err: at androidx.lifecycle.LiveData$1.run(LiveData.java:93) 03-10 10:22:36.476 16047 16047 W System.err: at android.os.Handler.handleCallback(Handler.java:938) 03-10 10:22:36.476 16047 16047 W System.err: at android.os.Handler.dispatchMessage(Handler.java:99) 03-10 10:22:36.476 16047 16047 W System.err: at android.os.Looper.loopOnce(Looper.java:201) 03-10 10:22:36.476 16047 16047 W System.err: at android.os.Looper.loop(Looper.java:288) 03-10 10:22:36.477 16047 16047 W System.err: at android.app.ActivityThread.main(ActivityThread.java:7839) 03-10 10:22:36.477 16047 16047 W System.err: at java.lang.reflect.Method.invoke(Native Method) 03-10 10:22:36.477 16047 16047 W System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 03-10 10:22:36.477 16047 16047 W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 03-10 10:22:36.477 16047 16047 E ETATest : Crash with message: setSpan (0 ... -1) has end before start 03-10 10:22:36.477 16047 16047 V ETATest : textViewLog Before: Starting… 03-10 10:22:36.477 16047 16047 V ETATest : Checking permission to access storage… Successful 03-10 10:22:36.477 16047 16047 V ETATest : Checking permission to access storage… Successful 03-10 10:22:36.477 16047 16047 V ETATest : Checking working directory permissions… Successful 03-10 10:22:36.477 16047 16047 V ETATest : 03-10 10:22:36.477 16047 16047 V ETATest : Processing /storage/emulated/0/DCIM/test_standard_addThumbsSettingsDefaultTwoRuns 03-10 10:22:36.477 16047 16047 V ETATest : spannableLog: Starting… 03-10 10:22:36.477 16047 16047 V ETATest : Checking permission to access storage… Successful 03-10 10:22:36.477 16047 16047 V ETATest : Checking permission to access storage… Successful 03-10 10:22:36.477 16047 16047 V ETATest : Checking working directory permissions… Successful 03-10 10:22:36.477 16047 16047 V ETATest : 03-10 10:22:36.477 16047 16047 V ETATest : Processing /storage/emulated/0/DCIM/test_standard_addThumbsSettingsDefaultTwoRuns 03-10 10:22:36.477 16047 16047 V ETATest : Checking permissions… Successful 03-10 10:22:36.477 16047 16047 V ETATest : textViewLog After: Starting… 03-10 10:22:36.477 16047 16047 V ETATest : Checking permission to access storage… Successful 03-10 10:22:36.477 16047 16047 V ETATest : Checking permission to access storage… Successful 03-10 10:22:36.477 16047 16047 V ETATest : Checking working directory permissions… Successful 03-10 10:22:36.477 16047 16047 V ETATest : 03-10 10:22:36.477 16047 16047 V ETATest : Processing /storage/emulated/0/DCIM/test_standard_addThumbsSettingsDefaultTwoRuns
备注:内容来源于stack exchange,提问作者usilo
相关产品推荐
相关产品推荐

