TypedArray.java revision 5c1207be90fdf296c1b83034b7c68915e1749284
1package android.content.res; 2 3import android.graphics.drawable.Drawable; 4import android.util.AttributeSet; 5import android.util.DisplayMetrics; 6import android.util.Log; 7import android.util.TypedValue; 8import com.android.internal.util.XmlUtils; 9 10import java.util.Arrays; 11 12/** 13 * Container for an array of values that were retrieved with 14 * {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)} 15 * or {@link Resources#obtainAttributes}. Be 16 * sure to call {@link #recycle} when done with them. 17 * 18 * The indices used to retrieve values from this structure correspond to 19 * the positions of the attributes given to obtainStyledAttributes. 20 */ 21public class TypedArray { 22 private final Resources mResources; 23 /*package*/ XmlBlock.Parser mXml; 24 /*package*/ int[] mRsrcs; 25 /*package*/ int[] mData; 26 /*package*/ int[] mIndices; 27 /*package*/ int mLength; 28 private TypedValue mValue = new TypedValue(); 29 30 /** 31 * Return the number of values in this array. 32 */ 33 public int length() { 34 return mLength; 35 } 36 37 /** 38 * Return the number of indices in the array that actually have data. 39 */ 40 public int getIndexCount() { 41 return mIndices[0]; 42 } 43 44 /** 45 * Return an index in the array that has data. 46 * 47 * @param at The index you would like to returned, ranging from 0 to 48 * {@link #getIndexCount()}. 49 * 50 * @return The index at the given offset, which can be used with 51 * {@link #getValue} and related APIs. 52 */ 53 public int getIndex(int at) { 54 return mIndices[1+at]; 55 } 56 57 /** 58 * Return the Resources object this array was loaded from. 59 */ 60 public Resources getResources() { 61 return mResources; 62 } 63 64 /** 65 * Retrieve the styled string value for the attribute at <var>index</var>. 66 * 67 * @param index Index of attribute to retrieve. 68 * 69 * @return CharSequence holding string data. May be styled. Returns 70 * null if the attribute is not defined. 71 */ 72 public CharSequence getText(int index) { 73 index *= AssetManager.STYLE_NUM_ENTRIES; 74 final int[] data = mData; 75 final int type = data[index+AssetManager.STYLE_TYPE]; 76 if (type == TypedValue.TYPE_NULL) { 77 return null; 78 } else if (type == TypedValue.TYPE_STRING) { 79 return loadStringValueAt(index); 80 } 81 82 TypedValue v = mValue; 83 if (getValueAt(index, v)) { 84 Log.w(Resources.TAG, "Converting to string: " + v); 85 return v.coerceToString(); 86 } 87 Log.w(Resources.TAG, "getString of bad type: 0x" 88 + Integer.toHexString(type)); 89 return null; 90 } 91 92 /** 93 * Retrieve the string value for the attribute at <var>index</var>. 94 * 95 * @param index Index of attribute to retrieve. 96 * 97 * @return String holding string data. Any styling information is 98 * removed. Returns null if the attribute is not defined. 99 */ 100 public String getString(int index) { 101 index *= AssetManager.STYLE_NUM_ENTRIES; 102 final int[] data = mData; 103 final int type = data[index+AssetManager.STYLE_TYPE]; 104 if (type == TypedValue.TYPE_NULL) { 105 return null; 106 } else if (type == TypedValue.TYPE_STRING) { 107 return loadStringValueAt(index).toString(); 108 } 109 110 TypedValue v = mValue; 111 if (getValueAt(index, v)) { 112 Log.w(Resources.TAG, "Converting to string: " + v); 113 CharSequence cs = v.coerceToString(); 114 return cs != null ? cs.toString() : null; 115 } 116 Log.w(Resources.TAG, "getString of bad type: 0x" 117 + Integer.toHexString(type)); 118 return null; 119 } 120 121 /** 122 * Retrieve the string value for the attribute at <var>index</var>, but 123 * only if that string comes from an immediate value in an XML file. That 124 * is, this does not allow references to string resources, string 125 * attributes, or conversions from other types. As such, this method 126 * will only return strings for TypedArray objects that come from 127 * attributes in an XML file. 128 * 129 * @param index Index of attribute to retrieve. 130 * 131 * @return String holding string data. Any styling information is 132 * removed. Returns null if the attribute is not defined or is not 133 * an immediate string value. 134 */ 135 public String getNonResourceString(int index) { 136 index *= AssetManager.STYLE_NUM_ENTRIES; 137 final int[] data = mData; 138 final int type = data[index+AssetManager.STYLE_TYPE]; 139 if (type == TypedValue.TYPE_STRING) { 140 final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE]; 141 if (cookie < 0) { 142 return mXml.getPooledString( 143 data[index+AssetManager.STYLE_DATA]).toString(); 144 } 145 } 146 return null; 147 } 148 149 /** 150 * Retrieve the boolean value for the attribute at <var>index</var>. 151 * 152 * @param index Index of attribute to retrieve. 153 * @param defValue Value to return if the attribute is not defined. 154 * 155 * @return Attribute boolean value, or defValue if not defined. 156 */ 157 public boolean getBoolean(int index, boolean defValue) { 158 index *= AssetManager.STYLE_NUM_ENTRIES; 159 final int[] data = mData; 160 final int type = data[index+AssetManager.STYLE_TYPE]; 161 if (type == TypedValue.TYPE_NULL) { 162 return defValue; 163 } else if (type >= TypedValue.TYPE_FIRST_INT 164 && type <= TypedValue.TYPE_LAST_INT) { 165 return data[index+AssetManager.STYLE_DATA] != 0; 166 } 167 168 TypedValue v = mValue; 169 if (getValueAt(index, v)) { 170 Log.w(Resources.TAG, "Converting to boolean: " + v); 171 return XmlUtils.convertValueToBoolean( 172 v.coerceToString(), defValue); 173 } 174 Log.w(Resources.TAG, "getBoolean of bad type: 0x" 175 + Integer.toHexString(type)); 176 return defValue; 177 } 178 179 /** 180 * Retrieve the integer value for the attribute at <var>index</var>. 181 * 182 * @param index Index of attribute to retrieve. 183 * @param defValue Value to return if the attribute is not defined. 184 * 185 * @return Attribute int value, or defValue if not defined. 186 */ 187 public int getInt(int index, int defValue) { 188 index *= AssetManager.STYLE_NUM_ENTRIES; 189 final int[] data = mData; 190 final int type = data[index+AssetManager.STYLE_TYPE]; 191 if (type == TypedValue.TYPE_NULL) { 192 return defValue; 193 } else if (type >= TypedValue.TYPE_FIRST_INT 194 && type <= TypedValue.TYPE_LAST_INT) { 195 return data[index+AssetManager.STYLE_DATA]; 196 } 197 198 TypedValue v = mValue; 199 if (getValueAt(index, v)) { 200 Log.w(Resources.TAG, "Converting to int: " + v); 201 return XmlUtils.convertValueToInt( 202 v.coerceToString(), defValue); 203 } 204 Log.w(Resources.TAG, "getInt of bad type: 0x" 205 + Integer.toHexString(type)); 206 return defValue; 207 } 208 209 /** 210 * Retrieve the float value for the attribute at <var>index</var>. 211 * 212 * @param index Index of attribute to retrieve. 213 * 214 * @return Attribute float value, or defValue if not defined.. 215 */ 216 public float getFloat(int index, float defValue) { 217 index *= AssetManager.STYLE_NUM_ENTRIES; 218 final int[] data = mData; 219 final int type = data[index+AssetManager.STYLE_TYPE]; 220 if (type == TypedValue.TYPE_NULL) { 221 return defValue; 222 } else if (type == TypedValue.TYPE_FLOAT) { 223 return Float.intBitsToFloat(data[index+AssetManager.STYLE_DATA]); 224 } else if (type >= TypedValue.TYPE_FIRST_INT 225 && type <= TypedValue.TYPE_LAST_INT) { 226 return data[index+AssetManager.STYLE_DATA]; 227 } 228 229 TypedValue v = mValue; 230 if (getValueAt(index, v)) { 231 Log.w(Resources.TAG, "Converting to float: " + v); 232 CharSequence str = v.coerceToString(); 233 if (str != null) { 234 return Float.parseFloat(str.toString()); 235 } 236 } 237 Log.w(Resources.TAG, "getFloat of bad type: 0x" 238 + Integer.toHexString(type)); 239 return defValue; 240 } 241 242 /** 243 * Retrieve the color value for the attribute at <var>index</var>. If 244 * the attribute references a color resource holding a complex 245 * {@link android.content.res.ColorStateList}, then the default color from 246 * the set is returned. 247 * 248 * @param index Index of attribute to retrieve. 249 * @param defValue Value to return if the attribute is not defined or 250 * not a resource. 251 * 252 * @return Attribute color value, or defValue if not defined. 253 */ 254 public int getColor(int index, int defValue) { 255 index *= AssetManager.STYLE_NUM_ENTRIES; 256 final int[] data = mData; 257 final int type = data[index+AssetManager.STYLE_TYPE]; 258 if (type == TypedValue.TYPE_NULL) { 259 return defValue; 260 } else if (type >= TypedValue.TYPE_FIRST_INT 261 && type <= TypedValue.TYPE_LAST_INT) { 262 return data[index+AssetManager.STYLE_DATA]; 263 } else if (type == TypedValue.TYPE_STRING) { 264 final TypedValue value = mValue; 265 if (getValueAt(index, value)) { 266 ColorStateList csl = mResources.loadColorStateList( 267 value, value.resourceId); 268 return csl.getDefaultColor(); 269 } 270 return defValue; 271 } 272 273 throw new UnsupportedOperationException("Can't convert to color: type=0x" 274 + Integer.toHexString(type)); 275 } 276 277 /** 278 * Retrieve the ColorStateList for the attribute at <var>index</var>. 279 * The value may be either a single solid color or a reference to 280 * a color or complex {@link android.content.res.ColorStateList} description. 281 * 282 * @param index Index of attribute to retrieve. 283 * 284 * @return ColorStateList for the attribute, or null if not defined. 285 */ 286 public ColorStateList getColorStateList(int index) { 287 final TypedValue value = mValue; 288 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) { 289 return mResources.loadColorStateList(value, value.resourceId); 290 } 291 return null; 292 } 293 294 /** 295 * Retrieve the integer value for the attribute at <var>index</var>. 296 * 297 * @param index Index of attribute to retrieve. 298 * @param defValue Value to return if the attribute is not defined or 299 * not a resource. 300 * 301 * @return Attribute integer value, or defValue if not defined. 302 */ 303 public int getInteger(int index, int defValue) { 304 index *= AssetManager.STYLE_NUM_ENTRIES; 305 final int[] data = mData; 306 final int type = data[index+AssetManager.STYLE_TYPE]; 307 if (type == TypedValue.TYPE_NULL) { 308 return defValue; 309 } else if (type >= TypedValue.TYPE_FIRST_INT 310 && type <= TypedValue.TYPE_LAST_INT) { 311 return data[index+AssetManager.STYLE_DATA]; 312 } 313 314 throw new UnsupportedOperationException("Can't convert to integer: type=0x" 315 + Integer.toHexString(type)); 316 } 317 318 /** 319 * Retrieve a dimensional unit attribute at <var>index</var>. Unit 320 * conversions are based on the current {@link DisplayMetrics} 321 * associated with the resources this {@link TypedArray} object 322 * came from. 323 * 324 * @param index Index of attribute to retrieve. 325 * @param defValue Value to return if the attribute is not defined or 326 * not a resource. 327 * 328 * @return Attribute dimension value multiplied by the appropriate 329 * metric, or defValue if not defined. 330 * 331 * @see #getDimensionPixelOffset 332 * @see #getDimensionPixelSize 333 */ 334 public float getDimension(int index, float defValue) { 335 index *= AssetManager.STYLE_NUM_ENTRIES; 336 final int[] data = mData; 337 final int type = data[index+AssetManager.STYLE_TYPE]; 338 if (type == TypedValue.TYPE_NULL) { 339 return defValue; 340 } else if (type == TypedValue.TYPE_DIMENSION) { 341 return TypedValue.complexToDimension( 342 data[index+AssetManager.STYLE_DATA], mResources.mMetrics); 343 } 344 345 throw new UnsupportedOperationException("Can't convert to dimension: type=0x" 346 + Integer.toHexString(type)); 347 } 348 349 /** 350 * Retrieve a dimensional unit attribute at <var>index</var> for use 351 * as an offset in raw pixels. This is the same as 352 * {@link #getDimension}, except the returned value is converted to 353 * integer pixels for you. An offset conversion involves simply 354 * truncating the base value to an integer. 355 * 356 * @param index Index of attribute to retrieve. 357 * @param defValue Value to return if the attribute is not defined or 358 * not a resource. 359 * 360 * @return Attribute dimension value multiplied by the appropriate 361 * metric and truncated to integer pixels, or defValue if not defined. 362 * 363 * @see #getDimension 364 * @see #getDimensionPixelSize 365 */ 366 public int getDimensionPixelOffset(int index, int defValue) { 367 index *= AssetManager.STYLE_NUM_ENTRIES; 368 final int[] data = mData; 369 final int type = data[index+AssetManager.STYLE_TYPE]; 370 if (type == TypedValue.TYPE_NULL) { 371 return defValue; 372 } else if (type == TypedValue.TYPE_DIMENSION) { 373 return TypedValue.complexToDimensionPixelOffset( 374 data[index+AssetManager.STYLE_DATA], mResources.mMetrics); 375 } 376 377 throw new UnsupportedOperationException("Can't convert to dimension: type=0x" 378 + Integer.toHexString(type)); 379 } 380 381 /** 382 * Retrieve a dimensional unit attribute at <var>index</var> for use 383 * as a size in raw pixels. This is the same as 384 * {@link #getDimension}, except the returned value is converted to 385 * integer pixels for use as a size. A size conversion involves 386 * rounding the base value, and ensuring that a non-zero base value 387 * is at least one pixel in size. 388 * 389 * @param index Index of attribute to retrieve. 390 * @param defValue Value to return if the attribute is not defined or 391 * not a resource. 392 * 393 * @return Attribute dimension value multiplied by the appropriate 394 * metric and truncated to integer pixels, or defValue if not defined. 395 * 396 * @see #getDimension 397 * @see #getDimensionPixelOffset 398 */ 399 public int getDimensionPixelSize(int index, int defValue) { 400 index *= AssetManager.STYLE_NUM_ENTRIES; 401 final int[] data = mData; 402 final int type = data[index+AssetManager.STYLE_TYPE]; 403 if (type == TypedValue.TYPE_NULL) { 404 return defValue; 405 } else if (type == TypedValue.TYPE_DIMENSION) { 406 return TypedValue.complexToDimensionPixelSize( 407 data[index+AssetManager.STYLE_DATA], mResources.mMetrics); 408 } 409 410 throw new UnsupportedOperationException("Can't convert to dimension: type=0x" 411 + Integer.toHexString(type)); 412 } 413 414 /** 415 * Special version of {@link #getDimensionPixelSize} for retrieving 416 * {@link android.view.ViewGroup}'s layout_width and layout_height 417 * attributes. This is only here for performance reasons; applications 418 * should use {@link #getDimensionPixelSize}. 419 * 420 * @param index Index of the attribute to retrieve. 421 * @param name Textual name of attribute for error reporting. 422 * 423 * @return Attribute dimension value multiplied by the appropriate 424 * metric and truncated to integer pixels. 425 */ 426 public int getLayoutDimension(int index, String name) { 427 index *= AssetManager.STYLE_NUM_ENTRIES; 428 final int[] data = mData; 429 final int type = data[index+AssetManager.STYLE_TYPE]; 430 if (type >= TypedValue.TYPE_FIRST_INT 431 && type <= TypedValue.TYPE_LAST_INT) { 432 return data[index+AssetManager.STYLE_DATA]; 433 } else if (type == TypedValue.TYPE_DIMENSION) { 434 return TypedValue.complexToDimensionPixelSize( 435 data[index+AssetManager.STYLE_DATA], mResources.mMetrics); 436 } 437 438 throw new RuntimeException(getPositionDescription() 439 + ": You must supply a " + name + " attribute."); 440 } 441 442 /** 443 * Special version of {@link #getDimensionPixelSize} for retrieving 444 * {@link android.view.ViewGroup}'s layout_width and layout_height 445 * attributes. This is only here for performance reasons; applications 446 * should use {@link #getDimensionPixelSize}. 447 * 448 * @param index Index of the attribute to retrieve. 449 * @param defValue The default value to return if this attribute is not 450 * default or contains the wrong type of data. 451 * 452 * @return Attribute dimension value multiplied by the appropriate 453 * metric and truncated to integer pixels. 454 */ 455 public int getLayoutDimension(int index, int defValue) { 456 index *= AssetManager.STYLE_NUM_ENTRIES; 457 final int[] data = mData; 458 final int type = data[index+AssetManager.STYLE_TYPE]; 459 if (type >= TypedValue.TYPE_FIRST_INT 460 && type <= TypedValue.TYPE_LAST_INT) { 461 return data[index+AssetManager.STYLE_DATA]; 462 } else if (type == TypedValue.TYPE_DIMENSION) { 463 return TypedValue.complexToDimensionPixelSize( 464 data[index+AssetManager.STYLE_DATA], mResources.mMetrics); 465 } 466 467 return defValue; 468 } 469 470 /** 471 * Retrieve a fractional unit attribute at <var>index</var>. 472 * 473 * @param index Index of attribute to retrieve. 474 * @param base The base value of this fraction. In other words, a 475 * standard fraction is multiplied by this value. 476 * @param pbase The parent base value of this fraction. In other 477 * words, a parent fraction (nn%p) is multiplied by this 478 * value. 479 * @param defValue Value to return if the attribute is not defined or 480 * not a resource. 481 * 482 * @return Attribute fractional value multiplied by the appropriate 483 * base value, or defValue if not defined. 484 */ 485 public float getFraction(int index, int base, int pbase, float defValue) { 486 index *= AssetManager.STYLE_NUM_ENTRIES; 487 final int[] data = mData; 488 final int type = data[index+AssetManager.STYLE_TYPE]; 489 if (type == TypedValue.TYPE_NULL) { 490 return defValue; 491 } else if (type == TypedValue.TYPE_FRACTION) { 492 return TypedValue.complexToFraction( 493 data[index+AssetManager.STYLE_DATA], base, pbase); 494 } 495 496 throw new UnsupportedOperationException("Can't convert to fraction: type=0x" 497 + Integer.toHexString(type)); 498 } 499 500 /** 501 * Retrieve the resource identifier for the attribute at 502 * <var>index</var>. Note that attribute resource as resolved when 503 * the overall {@link TypedArray} object is retrieved. As a 504 * result, this function will return the resource identifier of the 505 * final resource value that was found, <em>not</em> necessarily the 506 * original resource that was specified by the attribute. 507 * 508 * @param index Index of attribute to retrieve. 509 * @param defValue Value to return if the attribute is not defined or 510 * not a resource. 511 * 512 * @return Attribute resource identifier, or defValue if not defined. 513 */ 514 public int getResourceId(int index, int defValue) { 515 index *= AssetManager.STYLE_NUM_ENTRIES; 516 final int[] data = mData; 517 if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) { 518 final int resid = data[index+AssetManager.STYLE_RESOURCE_ID]; 519 if (resid != 0) { 520 return resid; 521 } 522 } 523 return defValue; 524 } 525 526 /** 527 * Retrieve the Drawable for the attribute at <var>index</var>. This 528 * gets the resource ID of the selected attribute, and uses 529 * {@link Resources#getDrawable Resources.getDrawable} of the owning 530 * Resources object to retrieve its Drawable. 531 * 532 * @param index Index of attribute to retrieve. 533 * 534 * @return Drawable for the attribute, or null if not defined. 535 */ 536 public Drawable getDrawable(int index) { 537 final TypedValue value = mValue; 538 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) { 539 if (false) { 540 System.out.println("******************************************************************"); 541 System.out.println("Got drawable resource: type=" 542 + value.type 543 + " str=" + value.string 544 + " int=0x" + Integer.toHexString(value.data) 545 + " cookie=" + value.assetCookie); 546 System.out.println("******************************************************************"); 547 } 548 return mResources.loadDrawable(value, value.resourceId); 549 } 550 return null; 551 } 552 553 /** 554 * Retrieve the CharSequence[] for the attribute at <var>index</var>. 555 * This gets the resource ID of the selected attribute, and uses 556 * {@link Resources#getTextArray Resources.getTextArray} of the owning 557 * Resources object to retrieve its String[]. 558 * 559 * @param index Index of attribute to retrieve. 560 * 561 * @return CharSequence[] for the attribute, or null if not defined. 562 */ 563 public CharSequence[] getTextArray(int index) { 564 final TypedValue value = mValue; 565 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) { 566 if (false) { 567 System.out.println("******************************************************************"); 568 System.out.println("Got drawable resource: type=" 569 + value.type 570 + " str=" + value.string 571 + " int=0x" + Integer.toHexString(value.data) 572 + " cookie=" + value.assetCookie); 573 System.out.println("******************************************************************"); 574 } 575 return mResources.getTextArray(value.resourceId); 576 } 577 return null; 578 } 579 580 /** 581 * Retrieve the raw TypedValue for the attribute at <var>index</var>. 582 * 583 * @param index Index of attribute to retrieve. 584 * @param outValue TypedValue object in which to place the attribute's 585 * data. 586 * 587 * @return Returns true if the value was retrieved, else false. 588 */ 589 public boolean getValue(int index, TypedValue outValue) { 590 return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue); 591 } 592 593 /** 594 * Determines whether there is an attribute at <var>index</var>. 595 * 596 * @param index Index of attribute to retrieve. 597 * 598 * @return True if the attribute has a value, false otherwise. 599 */ 600 public boolean hasValue(int index) { 601 index *= AssetManager.STYLE_NUM_ENTRIES; 602 final int[] data = mData; 603 final int type = data[index+AssetManager.STYLE_TYPE]; 604 return type != TypedValue.TYPE_NULL; 605 } 606 607 /** 608 * Retrieve the raw TypedValue for the attribute at <var>index</var> 609 * and return a temporary object holding its data. This object is only 610 * valid until the next call on to {@link TypedArray}. 611 * 612 * @param index Index of attribute to retrieve. 613 * 614 * @return Returns a TypedValue object if the attribute is defined, 615 * containing its data; otherwise returns null. (You will not 616 * receive a TypedValue whose type is TYPE_NULL.) 617 */ 618 public TypedValue peekValue(int index) { 619 final TypedValue value = mValue; 620 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) { 621 return value; 622 } 623 return null; 624 } 625 626 /** 627 * Returns a message about the parser state suitable for printing error messages. 628 */ 629 public String getPositionDescription() { 630 return mXml != null ? mXml.getPositionDescription() : "<internal>"; 631 } 632 633 /** 634 * Give back a previously retrieved StyledAttributes, for later re-use. 635 */ 636 public void recycle() { 637 synchronized (mResources.mTmpValue) { 638 TypedArray cached = mResources.mCachedStyledAttributes; 639 if (cached == null || cached.mData.length < mData.length) { 640 mXml = null; 641 mResources.mCachedStyledAttributes = this; 642 } 643 } 644 } 645 646 private boolean getValueAt(int index, TypedValue outValue) { 647 final int[] data = mData; 648 final int type = data[index+AssetManager.STYLE_TYPE]; 649 if (type == TypedValue.TYPE_NULL) { 650 return false; 651 } 652 outValue.type = type; 653 outValue.data = data[index+AssetManager.STYLE_DATA]; 654 outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE]; 655 outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID]; 656 outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS]; 657 outValue.density = data[index+AssetManager.STYLE_DENSITY]; 658 if (type == TypedValue.TYPE_STRING) { 659 outValue.string = loadStringValueAt(index); 660 } 661 return true; 662 } 663 664 private CharSequence loadStringValueAt(int index) { 665 final int[] data = mData; 666 final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE]; 667 if (cookie < 0) { 668 if (mXml != null) { 669 return mXml.getPooledString( 670 data[index+AssetManager.STYLE_DATA]); 671 } 672 return null; 673 } 674 //System.out.println("Getting pooled from: " + v); 675 return mResources.mAssets.getPooledString( 676 cookie, data[index+AssetManager.STYLE_DATA]); 677 } 678 679 /*package*/ TypedArray(Resources resources, int[] data, int[] indices, int len) { 680 mResources = resources; 681 mData = data; 682 mIndices = indices; 683 mLength = len; 684 } 685 686 public String toString() { 687 return Arrays.toString(mData); 688 } 689}