Loading core/java/android/content/res/TypedArray.java +22 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,26 @@ public class TypedArray { * not be coerced to a string. * @throws RuntimeException if the TypedArray has already been recycled. */ @Nullable public String getString(int index) { return getString(index, true); } /** * Returns a string representation of the value at the given index, * optionally throwing a resource mismatch strict mode violation if the * value must be coerced to a string. * * @param index the index of the attribute to retrieve * @param strict {@code true} to throw a strict mode violation for string * coercion, {@code false} otherwise * @return a string representation of the value at the given index, or * {@code null} if the resource could not be coerced to a string * @see StrictMode#noteResourceMismatch(Object) * @hide Used internally for view attribute inspection. */ @Nullable public String getString(int index, boolean strict) { if (mRecycled) { throw new RuntimeException("Cannot make calls to a recycled instance!"); } Loading @@ -197,7 +216,9 @@ public class TypedArray { final TypedValue v = mValue; if (getValueAt(index, v)) { if (strict) { StrictMode.noteResourceMismatch(v); } final CharSequence cs = v.coerceToString(); return cs != null ? cs.toString() : null; } Loading core/java/android/view/View.java +39 −26 Original line number Diff line number Diff line Loading @@ -4457,47 +4457,60 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static SparseArray<String> getAttributeMap() { if (mAttributeMap == null) { mAttributeMap = new SparseArray<String>(); mAttributeMap = new SparseArray<>(); } return mAttributeMap; } private void saveAttributeData(AttributeSet attrs, TypedArray a) { int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2; mAttributes = new String[length]; private void saveAttributeData(@Nullable AttributeSet attrs, @NonNull TypedArray t) { final int attrsCount = attrs == null ? 0 : attrs.getAttributeCount(); final int indexCount = t.getIndexCount(); final String[] attributes = new String[(attrsCount + indexCount) * 2]; int i = 0; if (attrs != null) { for (i = 0; i < attrs.getAttributeCount(); i += 2) { mAttributes[i] = attrs.getAttributeName(i); mAttributes[i + 1] = attrs.getAttributeValue(i); // Store raw XML attributes. for (int j = 0; j < attrsCount; ++j) { attributes[i] = attrs.getAttributeName(j); attributes[i + 1] = attrs.getAttributeValue(j); i += 2; } // Store resolved styleable attributes. final Resources res = t.getResources(); final SparseArray<String> attributeMap = getAttributeMap(); for (int j = 0; j < indexCount; ++j) { final int index = t.getIndex(j); if (!t.hasValueOrEmpty(index)) { // Value is undefined. Skip it. continue; } SparseArray<String> attributeMap = getAttributeMap(); for (int j = 0; j < a.length(); ++j) { if (a.hasValue(j)) { try { int resourceId = a.getResourceId(j, 0); final int resourceId = t.getResourceId(index, 0); if (resourceId == 0) { // Value is not a reference. Skip it. continue; } String resourceName = attributeMap.get(resourceId); if (resourceName == null) { resourceName = a.getResources().getResourceName(resourceId); try { resourceName = res.getResourceName(resourceId); } catch (Resources.NotFoundException e) { resourceName = "0x" + Integer.toHexString(resourceId); } attributeMap.put(resourceId, resourceName); } mAttributes[i] = resourceName; mAttributes[i + 1] = a.getText(j).toString(); attributes[i] = resourceName; attributes[i + 1] = t.getString(index, false); i += 2; } catch (Resources.NotFoundException e) { // if we can't get the resource name, we just ignore it } } } // Trim to fit contents. final String[] trimmed = new String[i]; System.arraycopy(attributes, 0, trimmed, 0, i); mAttributes = trimmed; } public String toString() { Loading Loading
core/java/android/content/res/TypedArray.java +22 −1 Original line number Diff line number Diff line Loading @@ -181,7 +181,26 @@ public class TypedArray { * not be coerced to a string. * @throws RuntimeException if the TypedArray has already been recycled. */ @Nullable public String getString(int index) { return getString(index, true); } /** * Returns a string representation of the value at the given index, * optionally throwing a resource mismatch strict mode violation if the * value must be coerced to a string. * * @param index the index of the attribute to retrieve * @param strict {@code true} to throw a strict mode violation for string * coercion, {@code false} otherwise * @return a string representation of the value at the given index, or * {@code null} if the resource could not be coerced to a string * @see StrictMode#noteResourceMismatch(Object) * @hide Used internally for view attribute inspection. */ @Nullable public String getString(int index, boolean strict) { if (mRecycled) { throw new RuntimeException("Cannot make calls to a recycled instance!"); } Loading @@ -197,7 +216,9 @@ public class TypedArray { final TypedValue v = mValue; if (getValueAt(index, v)) { if (strict) { StrictMode.noteResourceMismatch(v); } final CharSequence cs = v.coerceToString(); return cs != null ? cs.toString() : null; } Loading
core/java/android/view/View.java +39 −26 Original line number Diff line number Diff line Loading @@ -4457,47 +4457,60 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static SparseArray<String> getAttributeMap() { if (mAttributeMap == null) { mAttributeMap = new SparseArray<String>(); mAttributeMap = new SparseArray<>(); } return mAttributeMap; } private void saveAttributeData(AttributeSet attrs, TypedArray a) { int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2; mAttributes = new String[length]; private void saveAttributeData(@Nullable AttributeSet attrs, @NonNull TypedArray t) { final int attrsCount = attrs == null ? 0 : attrs.getAttributeCount(); final int indexCount = t.getIndexCount(); final String[] attributes = new String[(attrsCount + indexCount) * 2]; int i = 0; if (attrs != null) { for (i = 0; i < attrs.getAttributeCount(); i += 2) { mAttributes[i] = attrs.getAttributeName(i); mAttributes[i + 1] = attrs.getAttributeValue(i); // Store raw XML attributes. for (int j = 0; j < attrsCount; ++j) { attributes[i] = attrs.getAttributeName(j); attributes[i + 1] = attrs.getAttributeValue(j); i += 2; } // Store resolved styleable attributes. final Resources res = t.getResources(); final SparseArray<String> attributeMap = getAttributeMap(); for (int j = 0; j < indexCount; ++j) { final int index = t.getIndex(j); if (!t.hasValueOrEmpty(index)) { // Value is undefined. Skip it. continue; } SparseArray<String> attributeMap = getAttributeMap(); for (int j = 0; j < a.length(); ++j) { if (a.hasValue(j)) { try { int resourceId = a.getResourceId(j, 0); final int resourceId = t.getResourceId(index, 0); if (resourceId == 0) { // Value is not a reference. Skip it. continue; } String resourceName = attributeMap.get(resourceId); if (resourceName == null) { resourceName = a.getResources().getResourceName(resourceId); try { resourceName = res.getResourceName(resourceId); } catch (Resources.NotFoundException e) { resourceName = "0x" + Integer.toHexString(resourceId); } attributeMap.put(resourceId, resourceName); } mAttributes[i] = resourceName; mAttributes[i + 1] = a.getText(j).toString(); attributes[i] = resourceName; attributes[i + 1] = t.getString(index, false); i += 2; } catch (Resources.NotFoundException e) { // if we can't get the resource name, we just ignore it } } } // Trim to fit contents. final String[] trimmed = new String[i]; System.arraycopy(attributes, 0, trimmed, 0, i); mAttributes = trimmed; } public String toString() { Loading