Merge "Enforce restrictions on recycled TypedArrays"
This commit is contained in:
committed by
Android (Google) Code Review
commit
7c495dcd11
@@ -1010,13 +1010,14 @@ public class PackageParser {
|
|||||||
pkg.mSharedUserLabel = sa.getResourceId(
|
pkg.mSharedUserLabel = sa.getResourceId(
|
||||||
com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
|
com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
|
||||||
}
|
}
|
||||||
sa.recycle();
|
|
||||||
|
|
||||||
pkg.installLocation = sa.getInteger(
|
pkg.installLocation = sa.getInteger(
|
||||||
com.android.internal.R.styleable.AndroidManifest_installLocation,
|
com.android.internal.R.styleable.AndroidManifest_installLocation,
|
||||||
PARSE_DEFAULT_INSTALL_LOCATION);
|
PARSE_DEFAULT_INSTALL_LOCATION);
|
||||||
pkg.applicationInfo.installLocation = pkg.installLocation;
|
pkg.applicationInfo.installLocation = pkg.installLocation;
|
||||||
|
|
||||||
|
sa.recycle();
|
||||||
|
|
||||||
/* Set the global "forward lock" flag */
|
/* Set the global "forward lock" flag */
|
||||||
if ((flags & PARSE_FORWARD_LOCK) != 0) {
|
if ((flags & PARSE_FORWARD_LOCK) != 0) {
|
||||||
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FORWARD_LOCK;
|
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FORWARD_LOCK;
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class TypedArray {
|
|||||||
attrs.mResources = res;
|
attrs.mResources = res;
|
||||||
attrs.mMetrics = res.getDisplayMetrics();
|
attrs.mMetrics = res.getDisplayMetrics();
|
||||||
attrs.mAssets = res.getAssets();
|
attrs.mAssets = res.getAssets();
|
||||||
|
attrs.mRecycled = false;
|
||||||
|
|
||||||
final int fullLen = len * AssetManager.STYLE_NUM_ENTRIES;
|
final int fullLen = len * AssetManager.STYLE_NUM_ENTRIES;
|
||||||
if (attrs.mData.length >= fullLen) {
|
if (attrs.mData.length >= fullLen) {
|
||||||
@@ -65,6 +66,8 @@ public class TypedArray {
|
|||||||
private Resources mResources;
|
private Resources mResources;
|
||||||
private DisplayMetrics mMetrics;
|
private DisplayMetrics mMetrics;
|
||||||
private AssetManager mAssets;
|
private AssetManager mAssets;
|
||||||
|
private boolean mRecycled;
|
||||||
|
|
||||||
/*package*/ XmlBlock.Parser mXml;
|
/*package*/ XmlBlock.Parser mXml;
|
||||||
/*package*/ Resources.Theme mTheme;
|
/*package*/ Resources.Theme mTheme;
|
||||||
/*package*/ int[] mData;
|
/*package*/ int[] mData;
|
||||||
@@ -76,6 +79,10 @@ public class TypedArray {
|
|||||||
* Return the number of values in this array.
|
* Return the number of values in this array.
|
||||||
*/
|
*/
|
||||||
public int length() {
|
public int length() {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
return mLength;
|
return mLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +90,10 @@ public class TypedArray {
|
|||||||
* Return the number of indices in the array that actually have data.
|
* Return the number of indices in the array that actually have data.
|
||||||
*/
|
*/
|
||||||
public int getIndexCount() {
|
public int getIndexCount() {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
return mIndices[0];
|
return mIndices[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +107,10 @@ public class TypedArray {
|
|||||||
* {@link #getValue} and related APIs.
|
* {@link #getValue} and related APIs.
|
||||||
*/
|
*/
|
||||||
public int getIndex(int at) {
|
public int getIndex(int at) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
return mIndices[1+at];
|
return mIndices[1+at];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +118,10 @@ public class TypedArray {
|
|||||||
* Return the Resources object this array was loaded from.
|
* Return the Resources object this array was loaded from.
|
||||||
*/
|
*/
|
||||||
public Resources getResources() {
|
public Resources getResources() {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
return mResources;
|
return mResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +134,10 @@ public class TypedArray {
|
|||||||
* null if the attribute is not defined.
|
* null if the attribute is not defined.
|
||||||
*/
|
*/
|
||||||
public CharSequence getText(int index) {
|
public CharSequence getText(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -143,6 +166,10 @@ public class TypedArray {
|
|||||||
* removed. Returns null if the attribute is not defined.
|
* removed. Returns null if the attribute is not defined.
|
||||||
*/
|
*/
|
||||||
public String getString(int index) {
|
public String getString(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -178,6 +205,10 @@ public class TypedArray {
|
|||||||
* an immediate string value.
|
* an immediate string value.
|
||||||
*/
|
*/
|
||||||
public String getNonResourceString(int index) {
|
public String getNonResourceString(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -204,6 +235,10 @@ public class TypedArray {
|
|||||||
* removed. Returns null if the attribute is not defined.
|
* removed. Returns null if the attribute is not defined.
|
||||||
*/
|
*/
|
||||||
public String getNonConfigurationString(int index, int allowedChangingConfigs) {
|
public String getNonConfigurationString(int index, int allowedChangingConfigs) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -236,6 +271,10 @@ public class TypedArray {
|
|||||||
* @return Attribute boolean value, or defValue if not defined.
|
* @return Attribute boolean value, or defValue if not defined.
|
||||||
*/
|
*/
|
||||||
public boolean getBoolean(int index, boolean defValue) {
|
public boolean getBoolean(int index, boolean defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -266,6 +305,10 @@ public class TypedArray {
|
|||||||
* @return Attribute int value, or defValue if not defined.
|
* @return Attribute int value, or defValue if not defined.
|
||||||
*/
|
*/
|
||||||
public int getInt(int index, int defValue) {
|
public int getInt(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -295,6 +338,10 @@ public class TypedArray {
|
|||||||
* @return Attribute float value, or defValue if not defined..
|
* @return Attribute float value, or defValue if not defined..
|
||||||
*/
|
*/
|
||||||
public float getFloat(int index, float defValue) {
|
public float getFloat(int index, float defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -333,6 +380,10 @@ public class TypedArray {
|
|||||||
* @return Attribute color value, or defValue if not defined.
|
* @return Attribute color value, or defValue if not defined.
|
||||||
*/
|
*/
|
||||||
public int getColor(int index, int defValue) {
|
public int getColor(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -365,6 +416,10 @@ public class TypedArray {
|
|||||||
* @return ColorStateList for the attribute, or null if not defined.
|
* @return ColorStateList for the attribute, or null if not defined.
|
||||||
*/
|
*/
|
||||||
public ColorStateList getColorStateList(int index) {
|
public ColorStateList getColorStateList(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
final TypedValue value = mValue;
|
final TypedValue value = mValue;
|
||||||
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
||||||
return mResources.loadColorStateList(value, value.resourceId);
|
return mResources.loadColorStateList(value, value.resourceId);
|
||||||
@@ -382,6 +437,10 @@ public class TypedArray {
|
|||||||
* @return Attribute integer value, or defValue if not defined.
|
* @return Attribute integer value, or defValue if not defined.
|
||||||
*/
|
*/
|
||||||
public int getInteger(int index, int defValue) {
|
public int getInteger(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -413,6 +472,10 @@ public class TypedArray {
|
|||||||
* @see #getDimensionPixelSize
|
* @see #getDimensionPixelSize
|
||||||
*/
|
*/
|
||||||
public float getDimension(int index, float defValue) {
|
public float getDimension(int index, float defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -445,6 +508,10 @@ public class TypedArray {
|
|||||||
* @see #getDimensionPixelSize
|
* @see #getDimensionPixelSize
|
||||||
*/
|
*/
|
||||||
public int getDimensionPixelOffset(int index, int defValue) {
|
public int getDimensionPixelOffset(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -478,6 +545,10 @@ public class TypedArray {
|
|||||||
* @see #getDimensionPixelOffset
|
* @see #getDimensionPixelOffset
|
||||||
*/
|
*/
|
||||||
public int getDimensionPixelSize(int index, int defValue) {
|
public int getDimensionPixelSize(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -505,6 +576,10 @@ public class TypedArray {
|
|||||||
* metric and truncated to integer pixels.
|
* metric and truncated to integer pixels.
|
||||||
*/
|
*/
|
||||||
public int getLayoutDimension(int index, String name) {
|
public int getLayoutDimension(int index, String name) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -534,6 +609,10 @@ public class TypedArray {
|
|||||||
* metric and truncated to integer pixels.
|
* metric and truncated to integer pixels.
|
||||||
*/
|
*/
|
||||||
public int getLayoutDimension(int index, int defValue) {
|
public int getLayoutDimension(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -564,6 +643,10 @@ public class TypedArray {
|
|||||||
* base value, or defValue if not defined.
|
* base value, or defValue if not defined.
|
||||||
*/
|
*/
|
||||||
public float getFraction(int index, int base, int pbase, float defValue) {
|
public float getFraction(int index, int base, int pbase, float defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -593,6 +676,10 @@ public class TypedArray {
|
|||||||
* @return Attribute resource identifier, or defValue if not defined.
|
* @return Attribute resource identifier, or defValue if not defined.
|
||||||
*/
|
*/
|
||||||
public int getResourceId(int index, int defValue) {
|
public int getResourceId(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
|
if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
|
||||||
@@ -615,6 +702,10 @@ public class TypedArray {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public int getThemeAttributeId(int index, int defValue) {
|
public int getThemeAttributeId(int index, int defValue) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
if (data[index + AssetManager.STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
|
if (data[index + AssetManager.STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
|
||||||
@@ -634,6 +725,10 @@ public class TypedArray {
|
|||||||
* @return Drawable for the attribute, or null if not defined.
|
* @return Drawable for the attribute, or null if not defined.
|
||||||
*/
|
*/
|
||||||
public Drawable getDrawable(int index) {
|
public Drawable getDrawable(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
final TypedValue value = mValue;
|
final TypedValue value = mValue;
|
||||||
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
||||||
if (false) {
|
if (false) {
|
||||||
@@ -661,6 +756,10 @@ public class TypedArray {
|
|||||||
* @return CharSequence[] for the attribute, or null if not defined.
|
* @return CharSequence[] for the attribute, or null if not defined.
|
||||||
*/
|
*/
|
||||||
public CharSequence[] getTextArray(int index) {
|
public CharSequence[] getTextArray(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
final TypedValue value = mValue;
|
final TypedValue value = mValue;
|
||||||
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
||||||
if (false) {
|
if (false) {
|
||||||
@@ -687,28 +786,11 @@ public class TypedArray {
|
|||||||
* @return Returns true if the value was retrieved, else false.
|
* @return Returns true if the value was retrieved, else false.
|
||||||
*/
|
*/
|
||||||
public boolean getValue(int index, TypedValue outValue) {
|
public boolean getValue(int index, TypedValue outValue) {
|
||||||
return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
|
if (mRecycled) {
|
||||||
}
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether this TypedArray contains an attribute of the specified
|
|
||||||
* type.
|
|
||||||
*
|
|
||||||
* @param type Type of data, e.g. {@link TypedValue#TYPE_ATTRIBUTE}
|
|
||||||
* @return True if the TypedArray contains an attribute of the specified
|
|
||||||
* type.
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public boolean hasType(int type) {
|
|
||||||
final int[] data = mData;
|
|
||||||
final int N = getIndexCount();
|
|
||||||
for (int i = 0; i < N; i++) {
|
|
||||||
final int index = getIndex(i) * AssetManager.STYLE_NUM_ENTRIES;
|
|
||||||
if (data[index + AssetManager.STYLE_TYPE] == type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -718,6 +800,10 @@ public class TypedArray {
|
|||||||
* @return Attribute type.
|
* @return Attribute type.
|
||||||
*/
|
*/
|
||||||
public int getType(int index) {
|
public int getType(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
return mData[index + AssetManager.STYLE_TYPE];
|
return mData[index + AssetManager.STYLE_TYPE];
|
||||||
}
|
}
|
||||||
@@ -730,6 +816,10 @@ public class TypedArray {
|
|||||||
* @return True if the attribute has a value, false otherwise.
|
* @return True if the attribute has a value, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean hasValue(int index) {
|
public boolean hasValue(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
index *= AssetManager.STYLE_NUM_ENTRIES;
|
index *= AssetManager.STYLE_NUM_ENTRIES;
|
||||||
final int[] data = mData;
|
final int[] data = mData;
|
||||||
final int type = data[index+AssetManager.STYLE_TYPE];
|
final int type = data[index+AssetManager.STYLE_TYPE];
|
||||||
@@ -748,6 +838,10 @@ public class TypedArray {
|
|||||||
* receive a TypedValue whose type is TYPE_NULL.)
|
* receive a TypedValue whose type is TYPE_NULL.)
|
||||||
*/
|
*/
|
||||||
public TypedValue peekValue(int index) {
|
public TypedValue peekValue(int index) {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
final TypedValue value = mValue;
|
final TypedValue value = mValue;
|
||||||
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
|
||||||
return value;
|
return value;
|
||||||
@@ -759,13 +853,23 @@ public class TypedArray {
|
|||||||
* Returns a message about the parser state suitable for printing error messages.
|
* Returns a message about the parser state suitable for printing error messages.
|
||||||
*/
|
*/
|
||||||
public String getPositionDescription() {
|
public String getPositionDescription() {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
return mXml != null ? mXml.getPositionDescription() : "<internal>";
|
return mXml != null ? mXml.getPositionDescription() : "<internal>";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give back a previously retrieved array, for later re-use.
|
* Recycle the TypedArray, to be re-used by a later caller. After calling
|
||||||
|
* this function you must not ever touch the typed array again.
|
||||||
*/
|
*/
|
||||||
public void recycle() {
|
public void recycle() {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException(toString() + " recycled twice!");
|
||||||
|
}
|
||||||
|
|
||||||
|
mRecycled = true;
|
||||||
mResources = null;
|
mResources = null;
|
||||||
mMetrics = null;
|
mMetrics = null;
|
||||||
mAssets = null;
|
mAssets = null;
|
||||||
@@ -791,6 +895,10 @@ public class TypedArray {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public int[] extractThemeAttrs() {
|
public int[] extractThemeAttrs() {
|
||||||
|
if (mRecycled) {
|
||||||
|
throw new RuntimeException("Cannot make calls to a recycled instance!");
|
||||||
|
}
|
||||||
|
|
||||||
int[] attrs = null;
|
int[] attrs = null;
|
||||||
|
|
||||||
final int N = length();
|
final int N = length();
|
||||||
|
|||||||
Reference in New Issue
Block a user