diff --git a/core/api/current.txt b/core/api/current.txt index a13f07e8fde07..2269354cda510 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -57703,7 +57703,7 @@ package android.widget { method public final void setSpannableFactory(android.text.Spannable.Factory); method public final void setText(CharSequence); method public void setText(CharSequence, android.widget.TextView.BufferType); - method public final void setText(char[], int, int); + method public final void setText(@NonNull char[], int, int); method public final void setText(@StringRes int); method public final void setText(@StringRes int, android.widget.TextView.BufferType); method public void setTextAppearance(@StyleRes int); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 83d77172031e0..b7bb09153fccf 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -6456,9 +6456,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public void setText(CharSequence text, BufferType type) { setText(text, type, true, 0); - if (mCharWrapper != null) { - mCharWrapper.mChars = null; - } + // drop any potential mCharWrappper leaks + mCharWrapper = null; } @UnsupportedAppUsage @@ -6672,11 +6671,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * since the TextView has no way to know that the text * has changed and that it needs to invalidate and re-layout. * + * @throws NullPointerException if text is null + * @throws IndexOutOfBoundsException if start or start+len are not in 0 to text.length + * * @param text char array to be displayed * @param start start index in the char array * @param len length of char count after {@code start} */ - public final void setText(char[] text, int start, int len) { + public final void setText(@NonNull char[] text, int start, int len) { int oldlen = 0; if (start < 0 || len < 0 || start + len > text.length) { @@ -13942,16 +13944,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } private static class CharWrapper implements CharSequence, GetChars, GraphicsOperations { + @NonNull private char[] mChars; private int mStart, mLength; - public CharWrapper(char[] chars, int start, int len) { + CharWrapper(@NonNull char[] chars, int start, int len) { mChars = chars; mStart = start; mLength = len; } - /* package */ void set(char[] chars, int start, int len) { + /* package */ void set(@NonNull char[] chars, int start, int len) { mChars = chars; mStart = start; mLength = len; diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java index 47ce2d87e69f4..cc4fbab1f1902 100644 --- a/core/tests/coretests/src/android/widget/TextViewTest.java +++ b/core/tests/coretests/src/android/widget/TextViewTest.java @@ -304,6 +304,23 @@ public class TextViewTest { assertFalse(mTextView.isCursorVisible()); } + @Test(expected = NullPointerException.class) + @UiThreadTest + public void setTextCharArrayNullThrows() { + mTextView = new TextView(mActivity); + mTextView.setText((char[]) null, 0, 0); + } + + @Test + @UiThreadTest + public void setTextCharArrayValidAfterSetTextString() { + mTextView = new TextView(mActivity); + mTextView.setText(new char[] { 'h', 'i'}, 0, 2); + CharSequence charWrapper = mTextView.getText(); + mTextView.setText("null out char wrapper"); + assertEquals("hi", charWrapper.toString()); + } + private String createLongText() { int size = 600 * 1000; final StringBuilder builder = new StringBuilder(size);