Android TextView выдает текстовую строку исключения IndexOutOfBoundsException.handleRun

#android

#Android

Вопрос:

Я получаю это исключение некоторое время назад, я не мог найти ничего полезного из трассировки стека, Crashlytics сообщает, что это происходит на Android 8 и 9

вот трассировка стека:

 Fatal Exception: java.lang.IndexOutOfBoundsException: measureLimit (54) is out of start (55) and limit (54) bounds
       at android.text.TextLine.handleRun(TextLine.java:989)
       at android.text.TextLine.measureRun(TextLine.java:500)
       at android.text.TextLine.measure(TextLine.java:337)
       at android.text.TextLine.metrics(TextLine.java:272)
       at android.text.Layout.getLineExtent(Layout.java:1370)
       at android.text.Layout.drawText(Layout.java:519)
       at android.text.Layout.draw(Layout.java:292)
       at android.widget.TextView.onDraw(TextView.java:7765)
       at android.view.View.draw(View.java:20370)
       at android.view.View.updateDisplayListIfDirty(View.java:19315)
       at android.view.View.draw(View.java:20093)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
       at android.view.View.updateDisplayListIfDirty(View.java:19306)
       at android.view.View.draw(View.java:20093)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
       at android.view.View.draw(View.java:20373)
       at android.support.v4.widget.NestedScrollView.draw(NestedScrollView.java:1888)
       at android.view.View.updateDisplayListIfDirty(View.java:19315)
       at android.view.View.draw(View.java:20093)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
       at android.support.design.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1246)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
       at android.view.View.updateDisplayListIfDirty(View.java:19306)
       at android.view.View.draw(View.java:20093)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
       at android.view.View.updateDisplayListIfDirty(View.java:19306)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
       at android.view.View.updateDisplayListIfDirty(View.java:19274)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
       at android.view.View.updateDisplayListIfDirty(View.java:19274)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
       at android.view.View.updateDisplayListIfDirty(View.java:19274)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
       at android.view.View.updateDisplayListIfDirty(View.java:19274)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
       at android.view.View.updateDisplayListIfDirty(View.java:19274)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
       at android.view.View.updateDisplayListIfDirty(View.java:19274)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4405)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4385)
       at android.view.View.updateDisplayListIfDirty(View.java:19274)
       at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
       at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
       at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800)
       at android.view.ViewRootImpl.draw(ViewRootImpl.java:3494)
       at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3281)
       at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2816)
       at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1785)
       at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7825)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
       at android.view.Choreographer.doCallbacks(Choreographer.java:723)
       at android.view.Choreographer.doFrame(Choreographer.java:658)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
       at android.os.Handler.handleCallback(Handler.java:789)
       at android.os.Handler.dispatchMessage(Handler.java:98)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6944)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
  

итак, трассировка стека не сообщает мне, что TextView происходит, я регистрирую экран, на котором происходит сбой, и на этом экране их много TextView , и я искал это по всему Интернету, но не смог увидеть ответа.

Обновить

Я подозреваю, что в этом коде он рисует закругленный фон для номера телефона в TextView

 public class RoundedBackgroundSpan extends ReplacementSpan implements LineHeightSpan {

    private static int CORNER_RADIUS = 8;
    private int backgroundColor = 0;
    private int textColor = 0;
    private int backgroundTranspernt;
    private float mTextSize = UIUtils.spToPx(16);

    private static final float PADDING_X = UIUtils.dp2px(4);
    private static final float PADDING_Y = UIUtils.dp2px(2);
    private static final float MAGIC_NUMBER = UIUtils.dp2px(2);

    public RoundedBackgroundSpan(Context context) {
        super();
        backgroundColor = context.getResources().getColor(R.color.NavigationBarStrokeColor);
        textColor = context.getResources().getColor(R.color.white);
        backgroundTranspernt = context.getResources().getColor(R.color.transparent);
    }

    public RoundedBackgroundSpan(Context context, @ColorRes int textColor,
                                 @ColorRes int backgroundColor) {
        super();
        this.backgroundColor = context.getResources().getColor(backgroundColor);
        this.textColor = context.getResources().getColor(textColor);
        backgroundTranspernt = context.getResources().getColor(backgroundColor);
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int
            y, int bottom, Paint paint) {


        paint = new Paint(paint); // make a copy for not editing the referenced paint

        paint.setTextSize(mTextSize);

        // Draw the rounded background
        paint.setColor(backgroundColor);
        float textHeightWrapping = UIUtils.dp2px(0);
        float tagBottom =
                top   textHeightWrapping   PADDING_Y   mTextSize   PADDING_Y   textHeightWrapping;
        float tagRight = x   getTagWidth(text, start, end, paint);
        RectF rect = new RectF(x, top, tagRight, tagBottom);
        canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint);

        // Draw the text
        paint.setColor(textColor);
        canvas.drawText(text, start, end, x   PADDING_X,
                tagBottom - PADDING_Y - textHeightWrapping - MAGIC_NUMBER, paint);

    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt
            fm) {
        paint = new Paint(paint); // make a copy for not editing the referenced paint
        paint.setTextSize(mTextSize);
        return getTagWidth(text, start, end, paint);
    }

    private int getTagWidth(CharSequence text, int start, int end, Paint paint) {
        return Math.round(PADDING_X   paint.measureText(text.subSequence(start, end).toString())   PADDING_X);
    }

    @Override
    public void chooseHeight(CharSequence text, int start, int end, int i2, int i3,
                             Paint.FontMetricsInt fontMetricsInt) {
        //we need to implement this so the text know the  line height
    }
}
  

Он маскирует телефон, чтобы сделать его интерактивным с помощью clickSpan

введите описание изображения здесь

Комментарии:

1. не могли бы вы показать нам свой код?

2. трассировка стека полностью является исходным кодом Android, ничего, что указывало бы на мой код.

3. в коде должен быть какой-то момент, когда происходит сбой

4. хорошо, если да, можете ли вы увидеть какую-либо строку, говорящую о пакете, отличном от Android? можете ли вы прочитать трассировку стека?

5. это сбой на устройстве Samsung с Android 8.0? У меня точно такая же проблема.. вы нашли решение?

Ответ №1:

Эта ошибка связана с добавлением текста в TextView . Закругленный фон, на который вы ссылаетесь, не имеет отношения к делу, поскольку ошибка относится конкретно к тексту, а не к какому-либо другому аспекту TextView .

Ошибка может возникнуть, если TextView управление выполняется из потока, отличного от основного потока. Убедитесь, что любой код, касающийся виджетов пользовательского интерфейса, выполняется только в главном потоке. Если вы используете RxJava, убедитесь, что вы правильно использовали observeOn(AndroidSchedulers.mainThread() там, где это необходимо.

Ответ №2:

Вероятно, в вашем тексте есть какие-то определенные символы, которые Android не может отобразить. Вероятно, какие-то невидимые специальные коды. Например, я сталкиваюсь с той же проблемой, когда у меня есть u200F в моем тексте.

Комментарии:

1. Могу подтвердить, что это просто глупо, произошел сбой из-за » n» внутри моего текста. Ищу обходной путь..

2. Хорошо, это была известная ошибка, комбинация составного текста специальные символы. Обходной путь: избегайте промежутков или gist.github.com/pyricau/3424004