Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find StringIndexOutOfBoundsException #49

Open
Sunaina015 opened this issue Nov 22, 2019 · 8 comments
Open

Find StringIndexOutOfBoundsException #49

Sunaina015 opened this issue Nov 22, 2019 · 8 comments

Comments

@Sunaina015
Copy link

Fatal Exception: java.lang.StringIndexOutOfBoundsException: length=9; index=70
at java.lang.String.getChars(String.java:788)
at android.text.TextUtils.getChars(TextUtils.java:103)
at android.text.SpannableStringBuilder.(SpannableStringBuilder.java:67)
at com.borjabravo.readmoretextview.ReadMoreTextView.updateCollapsedText(ReadMoreTextView.java:137)
at com.borjabravo.readmoretextview.ReadMoreTextView.getTrimmedText(ReadMoreTextView.java:114)
at com.borjabravo.readmoretextview.ReadMoreTextView.getDisplayableText(ReadMoreTextView.java:90)
at com.borjabravo.readmoretextview.ReadMoreTextView.setText(ReadMoreTextView.java:84)
at com.borjabravo.readmoretextview.ReadMoreTextView.setText(ReadMoreTextView.java:97)
at android.widget.TextView.setText(TextView.java:5553)
at w3bminds.engVarta.app.Adapters.ReviewAdapter.onBindViewHolder(ReviewAdapter.java:120)
at w3bminds.engVarta.app.Adapters.ReviewAdapter.onBindViewHolder(ReviewAdapter.java:66)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:286)
at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:343)
at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:359)
at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:366)
at android.support.v7.widget.GapWorker.run(GapWorker.java:397)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

@radubn
Copy link

radubn commented Jan 17, 2020

Same for me. Some xml:

<com.borjabravo.readmoretextview.ReadMoreTextView android:id="@+id/tv_description" android:layout_width="match_parent" android:layout_height="wrap_content" android:lineSpacingExtra="2dp" app:showTrimExpandedText="false" app:colorClickableText="@color/colorPrimary" app:trimLines="4" app:trimMode="trimModeLine" app:trimCollapsedText="@string/see_more"/>

The error:

`Fatal Exception: java.lang.StringIndexOutOfBoundsException
length=27; index=178

java.lang.String.getChars (String.java:788)
android.text.TextUtils.getChars (TextUtils.java:103)
android.text.SpannableStringBuilder. (SpannableStringBuilder.java:67)
com.borjabravo.readmoretextview.ReadMoreTextView.updateCollapsedText (ReadMoreTextView.java:137)
com.borjabravo.readmoretextview.ReadMoreTextView.getTrimmedText (ReadMoreTextView.java:114)
com.borjabravo.readmoretextview.ReadMoreTextView.getDisplayableText (ReadMoreTextView.java:90)
com.borjabravo.readmoretextview.ReadMoreTextView.setText (ReadMoreTextView.java:84)
com.borjabravo.readmoretextview.ReadMoreTextView.setText (ReadMoreTextView.java:97)`

It's in a RecyclerView, and no other operations are done, other than setting the text on the view.

@UmairAhmed420
Copy link

any workaround for this you guys found ?

@radubn
Copy link

radubn commented May 26, 2020

Not yet. The biggest problem is that I cannot replicate the bug.

@ShareemGelitoTeofilo
Copy link

ShareemGelitoTeofilo commented Jun 18, 2021

I've tried debugging this and I found that this part right here is causing it.

On this method of ReadMoreTextView.java

private CharSequence updateCollapsedText() {
        int trimEndIndex = text.length();
        switch (trimMode) {
            case TRIM_MODE_LINES:
                trimEndIndex = lineEndIndex - (ELLIPSIZE.length() + trimCollapsedText.length() + 1);
                if (trimEndIndex < 0) {
                    trimEndIndex = trimLength + 1;
                }
                break;
            case TRIM_MODE_LENGTH:
                trimEndIndex = trimLength + 1;
                break;
        }
        SpannableStringBuilder s = new SpannableStringBuilder(text, 0, trimEndIndex)
                .append(ELLIPSIZE)
                .append(trimCollapsedText);
        return addClickableSpan(s, trimCollapsedText);
    }

When you set the mode to TRIM_MODE_LINES, that case will execute and there are times that the value of trimEndIndex is negative so the if statement below it will execute and when trimLength is greater than the actual text length, this will cause the SpannableStringBuilder to throw and index out of bounds error.

ps. the trimLength have a default value of 240

@UmairAhmed420
Copy link

@ShareemGelitoTeofilo i know this cause the issue.... i want solution about this

@ShareemGelitoTeofilo
Copy link

I'm still looking for ways. Hope you guys can figure this out as well and share it here. I'll share mine as soon as I figure it out.

@ShareemGelitoTeofilo
Copy link

Maybe we could discuss solutions here

@ShareemGelitoTeofilo
Copy link

ShareemGelitoTeofilo commented Jun 19, 2021

If you're using a recyclerview with this.

I found out that one of the reasons for this is old data is still there, because of the recycling mechanism of recyclerview. What I mean is the old text is still there and it was used to calculate other variables within the ReadMoreTextView to initialize it, so by the time that the new text is passed into it will used the precomputed values from the old data. In this case the length of the old text is used to initialize the SpannableStringBuilder which caused the index out of bounds.

I added a setting to recyclerview to disable the recycling mechanism to avoid this issue. Altho it solved it, but it beats the purpose of the recyclerview and it obviously affected the performance. Have to find another way for this. Maybe put a handler inside the ReadMoreTextView to update the data effectively or wait for the recyclerview to finally load the new data first, but don't know how yet. Hope this will help others to figure out this problem once and for all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants