grantland / android-autofittextview

A TextView that automatically resizes text to fit perfectly within its bounds.
Apache License 2.0
4.27k stars 689 forks source link

StackOverflowError in getTextSize() on line 306 #11

Closed tom91136 closed 9 years ago

tom91136 commented 10 years ago

While trying with various Japanese strings, I've encountered a StackOverflowError:

java.lang.StackOverflowError
            at android.text.TextUtils.getChars(TextUtils.java:73)
            at android.text.MeasuredText.setPara(MeasuredText.java:106)
            at android.text.StaticLayout.generate(StaticLayout.java:239)
            at android.text.StaticLayout.<init>(StaticLayout.java:140)
            at android.text.StaticLayout.<init>(StaticLayout.java:90)
            at android.text.StaticLayout.<init>(StaticLayout.java:68)
            at android.text.StaticLayout.<init>(StaticLayout.java:48)
            at me.grantland.widget.AutofitTextView.getTextSize(AutofitTextView.java:297)
            at me.grantland.widget.AutofitTextView.getTextSize(AutofitTextView.java:306)
            at me.grantland.widget.AutofitTextView.getTextSize(AutofitTextView.java:306)
            at me.grantland.widget.AutofitTextView.getTextSize(AutofitTextView.java:306)
            at me.grantland.widget.AutofitTextView.getTextSize(AutofitTextView.java:306)
            at me.grantland.widget.AutofitTextView.getTextSize(AutofitTextView.java:306)
            // goes on repeating ......

getTextSize() gets caught in an infinite loop while doing a binary search looking for the best size. The String I'm trying to display is this:

キスアト

Note that this is not the only String that crashes, any random Japanese Strings could cause a crash. Another example

美少女写真館 番外編 OUTSIDE STORY

This seems to be related to encoding....

Benjamin1333 commented 10 years ago

Same problem here. Really annoying

grantland commented 10 years ago

Would you be able to describe what you used to reproduce this such as Android version and view attrs (height, width, maxLines, etc.)?

I tried to reproduce this on android-19 with android:maxLines="1" and android:maxLines="2" by copying and pasting 美少女写真館 番外編 OUTSIDE STORY and then deleting characters individually and didn't encounter any crashes.

devilkin64 commented 10 years ago

I meet the same problem, it's an algorithm precision issue in binary search(getTextSize). it's not a encoding error.

devilkin64 commented 10 years ago
    //Handle algorithm precision issue
    if((Math.abs(lineCount - maxLines) <= 1 ) && (high - low)< precision) {
        return low;
    }

BTW, 美少女写真館 means Pretty Yound Ladies Photo Gallery. ( ̄∀ ̄)

tom91136 commented 10 years ago

Is this fixed? Now that I know it's a precision problem, I'll see if I can make a more concrete reproduction.

grantland commented 10 years ago

I'm not sure, as I was unable to reproduce it.

zhiyou007 commented 10 years ago

java.lang.StackOverflowError at android.graphics.Paint.getTextRunAdvances(Paint.java:1720) at android.text.MeasuredText.addStyleRun(MeasuredText.java:173) at android.text.StaticLayout.generate(StaticLayout.java:273) at android.text.StaticLayout.(StaticLayout.java:140) at android.text.StaticLayout.(StaticLayout.java:90) at android.text.StaticLayout.(StaticLayout.java:68) at android.text.StaticLayout.(StaticLayout.java:48) at com.wzm.moviepic.weight.AutofitTextView.getTextSize(AutofitTextView.java:308) at com.wzm.moviepic.weight.AutofitTextView.getTextSize(AutofitTextView.java:308) at com.wzm.moviepic.weight.AutofitTextView.getTextSize(AutofitTextView.java:308) at com.wzm.moviepic.weight.AutofitTextView.getTextSize(AutofitTextView.java:308) at com.wzm.moviepic.weight.AutofitTextView.getTextSize(AutofitTextView.java:308) .......

device report 设备 操作系统 错误次数 青橙 4.2.2 3 红米手机 4.2.1 2 红米手机 4.2.2 1 2014011 4.2.2 1 三星Galaxy Win 4.2.2 1 三星Galaxy Grand 4.2.2 1 三星Galaxy Note 8.0 4.1.2 2 三星Galaxy Note II 4.3 3 三星Galaxy Note II 4.1.2 1 三星Galaxy Note II 4.3 2 华为荣耀3C 4.4.2 2 七喜H701 2.3.4 1 HM 1SC 4.3 3 HM 1SW 4.3 1 HM NOTE 1W 4.2.2 3 海尔I617 2.3.5 6 HUAWEI B199 4.3 2 HUAWEI C8813Q 4.1.2 2 HUAWEI P7-L00 4.4.2 1 LG E988 4.1.2 3

ubdc commented 10 years ago

<me.grantland.widget.AutofitTextView android:id="@+id/output_autofit" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" autofit:minTextSize="16sp" android:maxLines="2" android:ellipsize="end" android:gravity="center" />

then

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.error); mAutofitOutput = (TextView)findViewById(R.id.output_autofit); mAutofitOutput.setText("hello world\n\n\n"); }

the "hello world\n\n\n" have 3 lines, so in AutoFitTextView.java line:310

if (lineCount > maxLines) { return getTextSize(text, paint, targetWidth, maxLines, low, mid, precision, displayMetrics); }

lineCount always equals 3, and maxLines always equals 2, the the step in to the infinite loop;

maybe help someone;

lastly, in my case ,my solution is add a method in my AutoFitTextView:

@Override public void setText(CharSequence text, BufferType type) { if (text != null) { text = text.toString().replaceAll("\s", ""); } super.setText(text, type); }

remove all blank charactor;

grantland commented 10 years ago

@ubdc - I would recommend sanitizing newlines from your strings before passing them into AutofitTextView.

Unfortunately I cannot fix this bug unless someone provides the exact view specifications including dimensions, padding/margin, font, textSize, textStyling, strings, etc. so I could reproduce this bug.

billylindeman commented 9 years ago

I'm getting crash reports with a similar issues

java.lang.StackOverflowError
       at android.text.MeasuredText.addStyleRun(MeasuredText.java:187)
       at android.text.MeasuredText.addStyleRun(MeasuredText.java:245)
       at android.text.StaticLayout.generate(StaticLayout.java:291)
       at android.text.StaticLayout.<init>(StaticLayout.java:143)
       at android.text.StaticLayout.<init>(StaticLayout.java:93)
       at android.text.StaticLayout.<init>(StaticLayout.java:71)
       at android.text.StaticLayout.<init>(StaticLayout.java:51)
       at me.grantland.widget.AutofitHelper.getAutofitTextSize(AutofitHelper.java:152)
       at me.grantland.widget.AutofitHelper.getAutofitTextSize(AutofitHelper.java:161)
       at me.grantland.widget.AutofitHelper.getAutofitTextSize(AutofitHelper.java:161)
       at me.grantland.widget.AutofitHelper.getAutofitTextSize(AutofitHelper.java:161)

Anyone figure out a workaround ? I can't personally reproduce it but I've got tons of crash reports coming in.

tom91136 commented 9 years ago

using the latest version (0.2.0), this still happens, here's the stacktrace:

java.lang.StackOverflowError
        at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1013)
        at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:913)
        at android.text.TextUtils.getChars(TextUtils.java:79)
        at android.text.MeasuredText.setPara(MeasuredText.java:106)
        at android.text.StaticLayout.generate(StaticLayout.java:239)
        at android.text.StaticLayout.<init>(StaticLayout.java:140)
        at android.text.StaticLayout.<init>(StaticLayout.java:90)
        at android.text.StaticLayout.<init>(StaticLayout.java:68)
        at android.text.StaticLayout.<init>(StaticLayout.java:48)
        at me.grantland.widget.AutofitHelper.getAutofitTextSize(AutofitHelper.java:152)
        at me.grantland.widget.AutofitHelper.getAutofitTextSize(AutofitHelper.java:161)
        at me.grantland.widget.AutofitHelper.getAutofitTextSize(AutofitHelper.java:161)
        ... and it goes on....

This is a showstopper, I'll see what I can do to reproduce and submit a patch...

mrdejant commented 9 years ago

I managed to reproduce this bug by changing system font size in settings. Every thing works great with normal size, but crashes with large size.

I tried this on Galaxy Nexus and Samsung Galaxy S3.

grantland commented 9 years ago

The repro looks to be setting/pasting text with more newline characters than maxLines, as long as maxLines is greater than 1.

grantland commented 9 years ago

Please review fix here: #32