1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 import android.util.Log; 20 import android.util.SparseArray; 21 22 import java.io.Serializable; 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.HashMap; 26 import java.util.Iterator; 27 import java.util.Map; 28 import java.util.Set; 29 30 /** 31 * A mapping from String values to various Parcelable types. 32 * 33 */ 34 public final class Bundle implements Parcelable, Cloneable { 35 private static final String LOG_TAG = "Bundle"; 36 public static final Bundle EMPTY; 37 38 static { 39 EMPTY = new Bundle(); 40 EMPTY.mMap = Collections.unmodifiableMap(new HashMap<String, Object>()); 41 } 42 43 // Invariant - exactly one of mMap / mParcelledData will be null 44 // (except inside a call to unparcel) 45 46 /* package */ Map<String, Object> mMap = null; 47 48 /* 49 * If mParcelledData is non-null, then mMap will be null and the 50 * data are stored as a Parcel containing a Bundle. When the data 51 * are unparcelled, mParcelledData willbe set to null. 52 */ 53 /* package */ Parcel mParcelledData = null; 54 55 private boolean mHasFds = false; 56 private boolean mFdsKnown = true; 57 private boolean mAllowFds = true; 58 59 /** 60 * The ClassLoader used when unparcelling data from mParcelledData. 61 */ 62 private ClassLoader mClassLoader; 63 64 /** 65 * Constructs a new, empty Bundle. 66 */ Bundle()67 public Bundle() { 68 mMap = new HashMap<String, Object>(); 69 mClassLoader = getClass().getClassLoader(); 70 } 71 72 /** 73 * Constructs a Bundle whose data is stored as a Parcel. The data 74 * will be unparcelled on first contact, using the assigned ClassLoader. 75 * 76 * @param parcelledData a Parcel containing a Bundle 77 */ Bundle(Parcel parcelledData)78 Bundle(Parcel parcelledData) { 79 readFromParcel(parcelledData); 80 } 81 Bundle(Parcel parcelledData, int length)82 /* package */ Bundle(Parcel parcelledData, int length) { 83 readFromParcelInner(parcelledData, length); 84 } 85 86 /** 87 * Constructs a new, empty Bundle that uses a specific ClassLoader for 88 * instantiating Parcelable and Serializable objects. 89 * 90 * @param loader An explicit ClassLoader to use when instantiating objects 91 * inside of the Bundle. 92 */ Bundle(ClassLoader loader)93 public Bundle(ClassLoader loader) { 94 mMap = new HashMap<String, Object>(); 95 mClassLoader = loader; 96 } 97 98 /** 99 * Constructs a new, empty Bundle sized to hold the given number of 100 * elements. The Bundle will grow as needed. 101 * 102 * @param capacity the initial capacity of the Bundle 103 */ Bundle(int capacity)104 public Bundle(int capacity) { 105 mMap = new HashMap<String, Object>(capacity); 106 mClassLoader = getClass().getClassLoader(); 107 } 108 109 /** 110 * Constructs a Bundle containing a copy of the mappings from the given 111 * Bundle. 112 * 113 * @param b a Bundle to be copied. 114 */ Bundle(Bundle b)115 public Bundle(Bundle b) { 116 if (b.mParcelledData != null) { 117 mParcelledData = Parcel.obtain(); 118 mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize()); 119 mParcelledData.setDataPosition(0); 120 } else { 121 mParcelledData = null; 122 } 123 124 if (b.mMap != null) { 125 mMap = new HashMap<String, Object>(b.mMap); 126 } else { 127 mMap = null; 128 } 129 130 mHasFds = b.mHasFds; 131 mFdsKnown = b.mFdsKnown; 132 mClassLoader = b.mClassLoader; 133 } 134 135 /** 136 * Make a Bundle for a single key/value pair. 137 * 138 * @hide 139 */ forPair(String key, String value)140 public static Bundle forPair(String key, String value) { 141 // TODO: optimize this case. 142 Bundle b = new Bundle(1); 143 b.putString(key, value); 144 return b; 145 } 146 147 /** 148 * TODO: optimize this later (getting just the value part of a Bundle 149 * with a single pair) once Bundle.forPair() above is implemented 150 * with a special single-value Map implementation/serialization. 151 * 152 * Note: value in single-pair Bundle may be null. 153 * 154 * @hide 155 */ getPairValue()156 public String getPairValue() { 157 unparcel(); 158 int size = mMap.size(); 159 if (size > 1) { 160 Log.w(LOG_TAG, "getPairValue() used on Bundle with multiple pairs."); 161 } 162 if (size == 0) { 163 return null; 164 } 165 Object o = mMap.values().iterator().next(); 166 try { 167 return (String) o; 168 } catch (ClassCastException e) { 169 typeWarning("getPairValue()", o, "String", e); 170 return null; 171 } 172 } 173 174 /** 175 * Changes the ClassLoader this Bundle uses when instantiating objects. 176 * 177 * @param loader An explicit ClassLoader to use when instantiating objects 178 * inside of the Bundle. 179 */ setClassLoader(ClassLoader loader)180 public void setClassLoader(ClassLoader loader) { 181 mClassLoader = loader; 182 } 183 184 /** 185 * Return the ClassLoader currently associated with this Bundle. 186 */ getClassLoader()187 public ClassLoader getClassLoader() { 188 return mClassLoader; 189 } 190 191 /** @hide */ setAllowFds(boolean allowFds)192 public boolean setAllowFds(boolean allowFds) { 193 boolean orig = mAllowFds; 194 mAllowFds = allowFds; 195 return orig; 196 } 197 198 /** 199 * Clones the current Bundle. The internal map is cloned, but the keys and 200 * values to which it refers are copied by reference. 201 */ 202 @Override clone()203 public Object clone() { 204 return new Bundle(this); 205 } 206 207 /** 208 * If the underlying data are stored as a Parcel, unparcel them 209 * using the currently assigned class loader. 210 */ unparcel()211 /* package */ synchronized void unparcel() { 212 if (mParcelledData == null) { 213 return; 214 } 215 216 int N = mParcelledData.readInt(); 217 if (N < 0) { 218 return; 219 } 220 if (mMap == null) { 221 mMap = new HashMap<String, Object>(); 222 } 223 mParcelledData.readMapInternal(mMap, N, mClassLoader); 224 mParcelledData.recycle(); 225 mParcelledData = null; 226 } 227 228 /** 229 * Returns the number of mappings contained in this Bundle. 230 * 231 * @return the number of mappings as an int. 232 */ size()233 public int size() { 234 unparcel(); 235 return mMap.size(); 236 } 237 238 /** 239 * Returns true if the mapping of this Bundle is empty, false otherwise. 240 */ isEmpty()241 public boolean isEmpty() { 242 unparcel(); 243 return mMap.isEmpty(); 244 } 245 246 /** 247 * Removes all elements from the mapping of this Bundle. 248 */ clear()249 public void clear() { 250 unparcel(); 251 mMap.clear(); 252 mHasFds = false; 253 mFdsKnown = true; 254 } 255 256 /** 257 * Returns true if the given key is contained in the mapping 258 * of this Bundle. 259 * 260 * @param key a String key 261 * @return true if the key is part of the mapping, false otherwise 262 */ containsKey(String key)263 public boolean containsKey(String key) { 264 unparcel(); 265 return mMap.containsKey(key); 266 } 267 268 /** 269 * Returns the entry with the given key as an object. 270 * 271 * @param key a String key 272 * @return an Object, or null 273 */ get(String key)274 public Object get(String key) { 275 unparcel(); 276 return mMap.get(key); 277 } 278 279 /** 280 * Removes any entry with the given key from the mapping of this Bundle. 281 * 282 * @param key a String key 283 */ remove(String key)284 public void remove(String key) { 285 unparcel(); 286 mMap.remove(key); 287 } 288 289 /** 290 * Inserts all mappings from the given Bundle into this Bundle. 291 * 292 * @param map a Bundle 293 */ putAll(Bundle map)294 public void putAll(Bundle map) { 295 unparcel(); 296 map.unparcel(); 297 mMap.putAll(map.mMap); 298 299 // fd state is now known if and only if both bundles already knew 300 mHasFds |= map.mHasFds; 301 mFdsKnown = mFdsKnown && map.mFdsKnown; 302 } 303 304 /** 305 * Returns a Set containing the Strings used as keys in this Bundle. 306 * 307 * @return a Set of String keys 308 */ keySet()309 public Set<String> keySet() { 310 unparcel(); 311 return mMap.keySet(); 312 } 313 314 /** 315 * Reports whether the bundle contains any parcelled file descriptors. 316 */ hasFileDescriptors()317 public boolean hasFileDescriptors() { 318 if (!mFdsKnown) { 319 boolean fdFound = false; // keep going until we find one or run out of data 320 321 if (mParcelledData != null) { 322 if (mParcelledData.hasFileDescriptors()) { 323 fdFound = true; 324 } 325 } else { 326 // It's been unparcelled, so we need to walk the map 327 Iterator<Map.Entry<String, Object>> iter = mMap.entrySet().iterator(); 328 while (!fdFound && iter.hasNext()) { 329 Object obj = iter.next().getValue(); 330 if (obj instanceof Parcelable) { 331 if ((((Parcelable)obj).describeContents() 332 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) { 333 fdFound = true; 334 break; 335 } 336 } else if (obj instanceof Parcelable[]) { 337 Parcelable[] array = (Parcelable[]) obj; 338 for (int n = array.length - 1; n >= 0; n--) { 339 if ((array[n].describeContents() 340 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) { 341 fdFound = true; 342 break; 343 } 344 } 345 } else if (obj instanceof SparseArray) { 346 SparseArray<? extends Parcelable> array = 347 (SparseArray<? extends Parcelable>) obj; 348 for (int n = array.size() - 1; n >= 0; n--) { 349 if ((array.get(n).describeContents() 350 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) { 351 fdFound = true; 352 break; 353 } 354 } 355 } else if (obj instanceof ArrayList) { 356 ArrayList array = (ArrayList) obj; 357 // an ArrayList here might contain either Strings or 358 // Parcelables; only look inside for Parcelables 359 if ((array.size() > 0) 360 && (array.get(0) instanceof Parcelable)) { 361 for (int n = array.size() - 1; n >= 0; n--) { 362 Parcelable p = (Parcelable) array.get(n); 363 if (p != null && ((p.describeContents() 364 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) { 365 fdFound = true; 366 break; 367 } 368 } 369 } 370 } 371 } 372 } 373 374 mHasFds = fdFound; 375 mFdsKnown = true; 376 } 377 return mHasFds; 378 } 379 380 /** 381 * Inserts a Boolean value into the mapping of this Bundle, replacing 382 * any existing value for the given key. Either key or value may be null. 383 * 384 * @param key a String, or null 385 * @param value a Boolean, or null 386 */ putBoolean(String key, boolean value)387 public void putBoolean(String key, boolean value) { 388 unparcel(); 389 mMap.put(key, value); 390 } 391 392 /** 393 * Inserts a byte value into the mapping of this Bundle, replacing 394 * any existing value for the given key. 395 * 396 * @param key a String, or null 397 * @param value a byte 398 */ putByte(String key, byte value)399 public void putByte(String key, byte value) { 400 unparcel(); 401 mMap.put(key, value); 402 } 403 404 /** 405 * Inserts a char value into the mapping of this Bundle, replacing 406 * any existing value for the given key. 407 * 408 * @param key a String, or null 409 * @param value a char, or null 410 */ putChar(String key, char value)411 public void putChar(String key, char value) { 412 unparcel(); 413 mMap.put(key, value); 414 } 415 416 /** 417 * Inserts a short value into the mapping of this Bundle, replacing 418 * any existing value for the given key. 419 * 420 * @param key a String, or null 421 * @param value a short 422 */ putShort(String key, short value)423 public void putShort(String key, short value) { 424 unparcel(); 425 mMap.put(key, value); 426 } 427 428 /** 429 * Inserts an int value into the mapping of this Bundle, replacing 430 * any existing value for the given key. 431 * 432 * @param key a String, or null 433 * @param value an int, or null 434 */ putInt(String key, int value)435 public void putInt(String key, int value) { 436 unparcel(); 437 mMap.put(key, value); 438 } 439 440 /** 441 * Inserts a long value into the mapping of this Bundle, replacing 442 * any existing value for the given key. 443 * 444 * @param key a String, or null 445 * @param value a long 446 */ putLong(String key, long value)447 public void putLong(String key, long value) { 448 unparcel(); 449 mMap.put(key, value); 450 } 451 452 /** 453 * Inserts a float value into the mapping of this Bundle, replacing 454 * any existing value for the given key. 455 * 456 * @param key a String, or null 457 * @param value a float 458 */ putFloat(String key, float value)459 public void putFloat(String key, float value) { 460 unparcel(); 461 mMap.put(key, value); 462 } 463 464 /** 465 * Inserts a double value into the mapping of this Bundle, replacing 466 * any existing value for the given key. 467 * 468 * @param key a String, or null 469 * @param value a double 470 */ putDouble(String key, double value)471 public void putDouble(String key, double value) { 472 unparcel(); 473 mMap.put(key, value); 474 } 475 476 /** 477 * Inserts a String value into the mapping of this Bundle, replacing 478 * any existing value for the given key. Either key or value may be null. 479 * 480 * @param key a String, or null 481 * @param value a String, or null 482 */ putString(String key, String value)483 public void putString(String key, String value) { 484 unparcel(); 485 mMap.put(key, value); 486 } 487 488 /** 489 * Inserts a CharSequence value into the mapping of this Bundle, replacing 490 * any existing value for the given key. Either key or value may be null. 491 * 492 * @param key a String, or null 493 * @param value a CharSequence, or null 494 */ putCharSequence(String key, CharSequence value)495 public void putCharSequence(String key, CharSequence value) { 496 unparcel(); 497 mMap.put(key, value); 498 } 499 500 /** 501 * Inserts a Parcelable value into the mapping of this Bundle, replacing 502 * any existing value for the given key. Either key or value may be null. 503 * 504 * @param key a String, or null 505 * @param value a Parcelable object, or null 506 */ putParcelable(String key, Parcelable value)507 public void putParcelable(String key, Parcelable value) { 508 unparcel(); 509 mMap.put(key, value); 510 mFdsKnown = false; 511 } 512 513 /** 514 * Inserts an array of Parcelable values into the mapping of this Bundle, 515 * replacing any existing value for the given key. Either key or value may 516 * be null. 517 * 518 * @param key a String, or null 519 * @param value an array of Parcelable objects, or null 520 */ putParcelableArray(String key, Parcelable[] value)521 public void putParcelableArray(String key, Parcelable[] value) { 522 unparcel(); 523 mMap.put(key, value); 524 mFdsKnown = false; 525 } 526 527 /** 528 * Inserts a List of Parcelable values into the mapping of this Bundle, 529 * replacing any existing value for the given key. Either key or value may 530 * be null. 531 * 532 * @param key a String, or null 533 * @param value an ArrayList of Parcelable objects, or null 534 */ putParcelableArrayList(String key, ArrayList<? extends Parcelable> value)535 public void putParcelableArrayList(String key, 536 ArrayList<? extends Parcelable> value) { 537 unparcel(); 538 mMap.put(key, value); 539 mFdsKnown = false; 540 } 541 542 /** 543 * Inserts a SparceArray of Parcelable values into the mapping of this 544 * Bundle, replacing any existing value for the given key. Either key 545 * or value may be null. 546 * 547 * @param key a String, or null 548 * @param value a SparseArray of Parcelable objects, or null 549 */ putSparseParcelableArray(String key, SparseArray<? extends Parcelable> value)550 public void putSparseParcelableArray(String key, 551 SparseArray<? extends Parcelable> value) { 552 unparcel(); 553 mMap.put(key, value); 554 mFdsKnown = false; 555 } 556 557 /** 558 * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing 559 * any existing value for the given key. Either key or value may be null. 560 * 561 * @param key a String, or null 562 * @param value an ArrayList<Integer> object, or null 563 */ putIntegerArrayList(String key, ArrayList<Integer> value)564 public void putIntegerArrayList(String key, ArrayList<Integer> value) { 565 unparcel(); 566 mMap.put(key, value); 567 } 568 569 /** 570 * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing 571 * any existing value for the given key. Either key or value may be null. 572 * 573 * @param key a String, or null 574 * @param value an ArrayList<String> object, or null 575 */ putStringArrayList(String key, ArrayList<String> value)576 public void putStringArrayList(String key, ArrayList<String> value) { 577 unparcel(); 578 mMap.put(key, value); 579 } 580 581 /** 582 * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing 583 * any existing value for the given key. Either key or value may be null. 584 * 585 * @param key a String, or null 586 * @param value an ArrayList<CharSequence> object, or null 587 */ putCharSequenceArrayList(String key, ArrayList<CharSequence> value)588 public void putCharSequenceArrayList(String key, ArrayList<CharSequence> value) { 589 unparcel(); 590 mMap.put(key, value); 591 } 592 593 /** 594 * Inserts a Serializable value into the mapping of this Bundle, replacing 595 * any existing value for the given key. Either key or value may be null. 596 * 597 * @param key a String, or null 598 * @param value a Serializable object, or null 599 */ putSerializable(String key, Serializable value)600 public void putSerializable(String key, Serializable value) { 601 unparcel(); 602 mMap.put(key, value); 603 } 604 605 /** 606 * Inserts a boolean array value into the mapping of this Bundle, replacing 607 * any existing value for the given key. Either key or value may be null. 608 * 609 * @param key a String, or null 610 * @param value a boolean array object, or null 611 */ putBooleanArray(String key, boolean[] value)612 public void putBooleanArray(String key, boolean[] value) { 613 unparcel(); 614 mMap.put(key, value); 615 } 616 617 /** 618 * Inserts a byte array value into the mapping of this Bundle, replacing 619 * any existing value for the given key. Either key or value may be null. 620 * 621 * @param key a String, or null 622 * @param value a byte array object, or null 623 */ putByteArray(String key, byte[] value)624 public void putByteArray(String key, byte[] value) { 625 unparcel(); 626 mMap.put(key, value); 627 } 628 629 /** 630 * Inserts a short array value into the mapping of this Bundle, replacing 631 * any existing value for the given key. Either key or value may be null. 632 * 633 * @param key a String, or null 634 * @param value a short array object, or null 635 */ putShortArray(String key, short[] value)636 public void putShortArray(String key, short[] value) { 637 unparcel(); 638 mMap.put(key, value); 639 } 640 641 /** 642 * Inserts a char array value into the mapping of this Bundle, replacing 643 * any existing value for the given key. Either key or value may be null. 644 * 645 * @param key a String, or null 646 * @param value a char array object, or null 647 */ putCharArray(String key, char[] value)648 public void putCharArray(String key, char[] value) { 649 unparcel(); 650 mMap.put(key, value); 651 } 652 653 /** 654 * Inserts an int array value into the mapping of this Bundle, replacing 655 * any existing value for the given key. Either key or value may be null. 656 * 657 * @param key a String, or null 658 * @param value an int array object, or null 659 */ putIntArray(String key, int[] value)660 public void putIntArray(String key, int[] value) { 661 unparcel(); 662 mMap.put(key, value); 663 } 664 665 /** 666 * Inserts a long array value into the mapping of this Bundle, replacing 667 * any existing value for the given key. Either key or value may be null. 668 * 669 * @param key a String, or null 670 * @param value a long array object, or null 671 */ putLongArray(String key, long[] value)672 public void putLongArray(String key, long[] value) { 673 unparcel(); 674 mMap.put(key, value); 675 } 676 677 /** 678 * Inserts a float array value into the mapping of this Bundle, replacing 679 * any existing value for the given key. Either key or value may be null. 680 * 681 * @param key a String, or null 682 * @param value a float array object, or null 683 */ putFloatArray(String key, float[] value)684 public void putFloatArray(String key, float[] value) { 685 unparcel(); 686 mMap.put(key, value); 687 } 688 689 /** 690 * Inserts a double array value into the mapping of this Bundle, replacing 691 * any existing value for the given key. Either key or value may be null. 692 * 693 * @param key a String, or null 694 * @param value a double array object, or null 695 */ putDoubleArray(String key, double[] value)696 public void putDoubleArray(String key, double[] value) { 697 unparcel(); 698 mMap.put(key, value); 699 } 700 701 /** 702 * Inserts a String array value into the mapping of this Bundle, replacing 703 * any existing value for the given key. Either key or value may be null. 704 * 705 * @param key a String, or null 706 * @param value a String array object, or null 707 */ putStringArray(String key, String[] value)708 public void putStringArray(String key, String[] value) { 709 unparcel(); 710 mMap.put(key, value); 711 } 712 713 /** 714 * Inserts a CharSequence array value into the mapping of this Bundle, replacing 715 * any existing value for the given key. Either key or value may be null. 716 * 717 * @param key a String, or null 718 * @param value a CharSequence array object, or null 719 */ putCharSequenceArray(String key, CharSequence[] value)720 public void putCharSequenceArray(String key, CharSequence[] value) { 721 unparcel(); 722 mMap.put(key, value); 723 } 724 725 /** 726 * Inserts a Bundle value into the mapping of this Bundle, replacing 727 * any existing value for the given key. Either key or value may be null. 728 * 729 * @param key a String, or null 730 * @param value a Bundle object, or null 731 */ putBundle(String key, Bundle value)732 public void putBundle(String key, Bundle value) { 733 unparcel(); 734 mMap.put(key, value); 735 } 736 737 /** 738 * Inserts an IBinder value into the mapping of this Bundle, replacing 739 * any existing value for the given key. Either key or value may be null. 740 * 741 * @param key a String, or null 742 * @param value an IBinder object, or null 743 * 744 * @deprecated 745 * @hide 746 */ 747 @Deprecated putIBinder(String key, IBinder value)748 public void putIBinder(String key, IBinder value) { 749 unparcel(); 750 mMap.put(key, value); 751 } 752 753 /** 754 * Returns the value associated with the given key, or false if 755 * no mapping of the desired type exists for the given key. 756 * 757 * @param key a String 758 * @return a boolean value 759 */ getBoolean(String key)760 public boolean getBoolean(String key) { 761 unparcel(); 762 return getBoolean(key, false); 763 } 764 765 // Log a message if the value was non-null but not of the expected type typeWarning(String key, Object value, String className, Object defaultValue, ClassCastException e)766 private void typeWarning(String key, Object value, String className, 767 Object defaultValue, ClassCastException e) { 768 StringBuilder sb = new StringBuilder(); 769 sb.append("Key "); 770 sb.append(key); 771 sb.append(" expected "); 772 sb.append(className); 773 sb.append(" but value was a "); 774 sb.append(value.getClass().getName()); 775 sb.append(". The default value "); 776 sb.append(defaultValue); 777 sb.append(" was returned."); 778 Log.w(LOG_TAG, sb.toString()); 779 Log.w(LOG_TAG, "Attempt to cast generated internal exception:", e); 780 } 781 typeWarning(String key, Object value, String className, ClassCastException e)782 private void typeWarning(String key, Object value, String className, 783 ClassCastException e) { 784 typeWarning(key, value, className, "<null>", e); 785 } 786 787 /** 788 * Returns the value associated with the given key, or defaultValue if 789 * no mapping of the desired type exists for the given key. 790 * 791 * @param key a String 792 * @return a boolean value 793 */ getBoolean(String key, boolean defaultValue)794 public boolean getBoolean(String key, boolean defaultValue) { 795 unparcel(); 796 Object o = mMap.get(key); 797 if (o == null) { 798 return defaultValue; 799 } 800 try { 801 return (Boolean) o; 802 } catch (ClassCastException e) { 803 typeWarning(key, o, "Boolean", defaultValue, e); 804 return defaultValue; 805 } 806 } 807 808 /** 809 * Returns the value associated with the given key, or (byte) 0 if 810 * no mapping of the desired type exists for the given key. 811 * 812 * @param key a String 813 * @return a byte value 814 */ getByte(String key)815 public byte getByte(String key) { 816 unparcel(); 817 return getByte(key, (byte) 0); 818 } 819 820 /** 821 * Returns the value associated with the given key, or defaultValue if 822 * no mapping of the desired type exists for the given key. 823 * 824 * @param key a String 825 * @return a byte value 826 */ getByte(String key, byte defaultValue)827 public Byte getByte(String key, byte defaultValue) { 828 unparcel(); 829 Object o = mMap.get(key); 830 if (o == null) { 831 return defaultValue; 832 } 833 try { 834 return (Byte) o; 835 } catch (ClassCastException e) { 836 typeWarning(key, o, "Byte", defaultValue, e); 837 return defaultValue; 838 } 839 } 840 841 /** 842 * Returns the value associated with the given key, or false if 843 * no mapping of the desired type exists for the given key. 844 * 845 * @param key a String 846 * @return a char value 847 */ getChar(String key)848 public char getChar(String key) { 849 unparcel(); 850 return getChar(key, (char) 0); 851 } 852 853 /** 854 * Returns the value associated with the given key, or (char) 0 if 855 * no mapping of the desired type exists for the given key. 856 * 857 * @param key a String 858 * @return a char value 859 */ getChar(String key, char defaultValue)860 public char getChar(String key, char defaultValue) { 861 unparcel(); 862 Object o = mMap.get(key); 863 if (o == null) { 864 return defaultValue; 865 } 866 try { 867 return (Character) o; 868 } catch (ClassCastException e) { 869 typeWarning(key, o, "Character", defaultValue, e); 870 return defaultValue; 871 } 872 } 873 874 /** 875 * Returns the value associated with the given key, or (short) 0 if 876 * no mapping of the desired type exists for the given key. 877 * 878 * @param key a String 879 * @return a short value 880 */ getShort(String key)881 public short getShort(String key) { 882 unparcel(); 883 return getShort(key, (short) 0); 884 } 885 886 /** 887 * Returns the value associated with the given key, or defaultValue if 888 * no mapping of the desired type exists for the given key. 889 * 890 * @param key a String 891 * @return a short value 892 */ getShort(String key, short defaultValue)893 public short getShort(String key, short defaultValue) { 894 unparcel(); 895 Object o = mMap.get(key); 896 if (o == null) { 897 return defaultValue; 898 } 899 try { 900 return (Short) o; 901 } catch (ClassCastException e) { 902 typeWarning(key, o, "Short", defaultValue, e); 903 return defaultValue; 904 } 905 } 906 907 /** 908 * Returns the value associated with the given key, or 0 if 909 * no mapping of the desired type exists for the given key. 910 * 911 * @param key a String 912 * @return an int value 913 */ getInt(String key)914 public int getInt(String key) { 915 unparcel(); 916 return getInt(key, 0); 917 } 918 919 /** 920 * Returns the value associated with the given key, or defaultValue if 921 * no mapping of the desired type exists for the given key. 922 * 923 * @param key a String 924 * @return an int value 925 */ getInt(String key, int defaultValue)926 public int getInt(String key, int defaultValue) { 927 unparcel(); 928 Object o = mMap.get(key); 929 if (o == null) { 930 return defaultValue; 931 } 932 try { 933 return (Integer) o; 934 } catch (ClassCastException e) { 935 typeWarning(key, o, "Integer", defaultValue, e); 936 return defaultValue; 937 } 938 } 939 940 /** 941 * Returns the value associated with the given key, or 0L if 942 * no mapping of the desired type exists for the given key. 943 * 944 * @param key a String 945 * @return a long value 946 */ getLong(String key)947 public long getLong(String key) { 948 unparcel(); 949 return getLong(key, 0L); 950 } 951 952 /** 953 * Returns the value associated with the given key, or defaultValue if 954 * no mapping of the desired type exists for the given key. 955 * 956 * @param key a String 957 * @return a long value 958 */ getLong(String key, long defaultValue)959 public long getLong(String key, long defaultValue) { 960 unparcel(); 961 Object o = mMap.get(key); 962 if (o == null) { 963 return defaultValue; 964 } 965 try { 966 return (Long) o; 967 } catch (ClassCastException e) { 968 typeWarning(key, o, "Long", defaultValue, e); 969 return defaultValue; 970 } 971 } 972 973 /** 974 * Returns the value associated with the given key, or 0.0f if 975 * no mapping of the desired type exists for the given key. 976 * 977 * @param key a String 978 * @return a float value 979 */ getFloat(String key)980 public float getFloat(String key) { 981 unparcel(); 982 return getFloat(key, 0.0f); 983 } 984 985 /** 986 * Returns the value associated with the given key, or defaultValue if 987 * no mapping of the desired type exists for the given key. 988 * 989 * @param key a String 990 * @return a float value 991 */ getFloat(String key, float defaultValue)992 public float getFloat(String key, float defaultValue) { 993 unparcel(); 994 Object o = mMap.get(key); 995 if (o == null) { 996 return defaultValue; 997 } 998 try { 999 return (Float) o; 1000 } catch (ClassCastException e) { 1001 typeWarning(key, o, "Float", defaultValue, e); 1002 return defaultValue; 1003 } 1004 } 1005 1006 /** 1007 * Returns the value associated with the given key, or 0.0 if 1008 * no mapping of the desired type exists for the given key. 1009 * 1010 * @param key a String 1011 * @return a double value 1012 */ getDouble(String key)1013 public double getDouble(String key) { 1014 unparcel(); 1015 return getDouble(key, 0.0); 1016 } 1017 1018 /** 1019 * Returns the value associated with the given key, or defaultValue if 1020 * no mapping of the desired type exists for the given key. 1021 * 1022 * @param key a String 1023 * @return a double value 1024 */ getDouble(String key, double defaultValue)1025 public double getDouble(String key, double defaultValue) { 1026 unparcel(); 1027 Object o = mMap.get(key); 1028 if (o == null) { 1029 return defaultValue; 1030 } 1031 try { 1032 return (Double) o; 1033 } catch (ClassCastException e) { 1034 typeWarning(key, o, "Double", defaultValue, e); 1035 return defaultValue; 1036 } 1037 } 1038 1039 /** 1040 * Returns the value associated with the given key, or null if 1041 * no mapping of the desired type exists for the given key or a null 1042 * value is explicitly associated with the key. 1043 * 1044 * @param key a String, or null 1045 * @return a String value, or null 1046 */ getString(String key)1047 public String getString(String key) { 1048 unparcel(); 1049 Object o = mMap.get(key); 1050 if (o == null) { 1051 return null; 1052 } 1053 try { 1054 return (String) o; 1055 } catch (ClassCastException e) { 1056 typeWarning(key, o, "String", e); 1057 return null; 1058 } 1059 } 1060 1061 /** 1062 * Returns the value associated with the given key, or defaultValue if 1063 * no mapping of the desired type exists for the given key. 1064 * 1065 * @param key a String, or null 1066 * @param defaultValue Value to return if key does not exist 1067 * @return a String value, or null 1068 */ getString(String key, String defaultValue)1069 public String getString(String key, String defaultValue) { 1070 unparcel(); 1071 Object o = mMap.get(key); 1072 if (o == null) { 1073 return defaultValue; 1074 } 1075 try { 1076 return (String) o; 1077 } catch (ClassCastException e) { 1078 typeWarning(key, o, "String", e); 1079 return defaultValue; 1080 } 1081 } 1082 1083 /** 1084 * Returns the value associated with the given key, or null if 1085 * no mapping of the desired type exists for the given key or a null 1086 * value is explicitly associated with the key. 1087 * 1088 * @param key a String, or null 1089 * @return a CharSequence value, or null 1090 */ getCharSequence(String key)1091 public CharSequence getCharSequence(String key) { 1092 unparcel(); 1093 Object o = mMap.get(key); 1094 if (o == null) { 1095 return null; 1096 } 1097 try { 1098 return (CharSequence) o; 1099 } catch (ClassCastException e) { 1100 typeWarning(key, o, "CharSequence", e); 1101 return null; 1102 } 1103 } 1104 1105 /** 1106 * Returns the value associated with the given key, or defaultValue if 1107 * no mapping of the desired type exists for the given key. 1108 * 1109 * @param key a String, or null 1110 * @param defaultValue Value to return if key does not exist 1111 * @return a CharSequence value, or null 1112 */ getCharSequence(String key, CharSequence defaultValue)1113 public CharSequence getCharSequence(String key, CharSequence defaultValue) { 1114 unparcel(); 1115 Object o = mMap.get(key); 1116 if (o == null) { 1117 return defaultValue; 1118 } 1119 try { 1120 return (CharSequence) o; 1121 } catch (ClassCastException e) { 1122 typeWarning(key, o, "CharSequence", e); 1123 return defaultValue; 1124 } 1125 } 1126 1127 /** 1128 * Returns the value associated with the given key, or null if 1129 * no mapping of the desired type exists for the given key or a null 1130 * value is explicitly associated with the key. 1131 * 1132 * @param key a String, or null 1133 * @return a Bundle value, or null 1134 */ getBundle(String key)1135 public Bundle getBundle(String key) { 1136 unparcel(); 1137 Object o = mMap.get(key); 1138 if (o == null) { 1139 return null; 1140 } 1141 try { 1142 return (Bundle) o; 1143 } catch (ClassCastException e) { 1144 typeWarning(key, o, "Bundle", e); 1145 return null; 1146 } 1147 } 1148 1149 /** 1150 * Returns the value associated with the given key, or null if 1151 * no mapping of the desired type exists for the given key or a null 1152 * value is explicitly associated with the key. 1153 * 1154 * @param key a String, or null 1155 * @return a Parcelable value, or null 1156 */ getParcelable(String key)1157 public <T extends Parcelable> T getParcelable(String key) { 1158 unparcel(); 1159 Object o = mMap.get(key); 1160 if (o == null) { 1161 return null; 1162 } 1163 try { 1164 return (T) o; 1165 } catch (ClassCastException e) { 1166 typeWarning(key, o, "Parcelable", e); 1167 return null; 1168 } 1169 } 1170 1171 /** 1172 * Returns the value associated with the given key, or null if 1173 * no mapping of the desired type exists for the given key or a null 1174 * value is explicitly associated with the key. 1175 * 1176 * @param key a String, or null 1177 * @return a Parcelable[] value, or null 1178 */ getParcelableArray(String key)1179 public Parcelable[] getParcelableArray(String key) { 1180 unparcel(); 1181 Object o = mMap.get(key); 1182 if (o == null) { 1183 return null; 1184 } 1185 try { 1186 return (Parcelable[]) o; 1187 } catch (ClassCastException e) { 1188 typeWarning(key, o, "Parcelable[]", e); 1189 return null; 1190 } 1191 } 1192 1193 /** 1194 * Returns the value associated with the given key, or null if 1195 * no mapping of the desired type exists for the given key or a null 1196 * value is explicitly associated with the key. 1197 * 1198 * @param key a String, or null 1199 * @return an ArrayList<T> value, or null 1200 */ getParcelableArrayList(String key)1201 public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String key) { 1202 unparcel(); 1203 Object o = mMap.get(key); 1204 if (o == null) { 1205 return null; 1206 } 1207 try { 1208 return (ArrayList<T>) o; 1209 } catch (ClassCastException e) { 1210 typeWarning(key, o, "ArrayList", e); 1211 return null; 1212 } 1213 } 1214 1215 /** 1216 * Returns the value associated with the given key, or null if 1217 * no mapping of the desired type exists for the given key or a null 1218 * value is explicitly associated with the key. 1219 * 1220 * @param key a String, or null 1221 * 1222 * @return a SparseArray of T values, or null 1223 */ getSparseParcelableArray(String key)1224 public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(String key) { 1225 unparcel(); 1226 Object o = mMap.get(key); 1227 if (o == null) { 1228 return null; 1229 } 1230 try { 1231 return (SparseArray<T>) o; 1232 } catch (ClassCastException e) { 1233 typeWarning(key, o, "SparseArray", e); 1234 return null; 1235 } 1236 } 1237 1238 /** 1239 * Returns the value associated with the given key, or null if 1240 * no mapping of the desired type exists for the given key or a null 1241 * value is explicitly associated with the key. 1242 * 1243 * @param key a String, or null 1244 * @return a Serializable value, or null 1245 */ getSerializable(String key)1246 public Serializable getSerializable(String key) { 1247 unparcel(); 1248 Object o = mMap.get(key); 1249 if (o == null) { 1250 return null; 1251 } 1252 try { 1253 return (Serializable) o; 1254 } catch (ClassCastException e) { 1255 typeWarning(key, o, "Serializable", e); 1256 return null; 1257 } 1258 } 1259 1260 /** 1261 * Returns the value associated with the given key, or null if 1262 * no mapping of the desired type exists for the given key or a null 1263 * value is explicitly associated with the key. 1264 * 1265 * @param key a String, or null 1266 * @return an ArrayList<String> value, or null 1267 */ getIntegerArrayList(String key)1268 public ArrayList<Integer> getIntegerArrayList(String key) { 1269 unparcel(); 1270 Object o = mMap.get(key); 1271 if (o == null) { 1272 return null; 1273 } 1274 try { 1275 return (ArrayList<Integer>) o; 1276 } catch (ClassCastException e) { 1277 typeWarning(key, o, "ArrayList<Integer>", e); 1278 return null; 1279 } 1280 } 1281 1282 /** 1283 * Returns the value associated with the given key, or null if 1284 * no mapping of the desired type exists for the given key or a null 1285 * value is explicitly associated with the key. 1286 * 1287 * @param key a String, or null 1288 * @return an ArrayList<String> value, or null 1289 */ getStringArrayList(String key)1290 public ArrayList<String> getStringArrayList(String key) { 1291 unparcel(); 1292 Object o = mMap.get(key); 1293 if (o == null) { 1294 return null; 1295 } 1296 try { 1297 return (ArrayList<String>) o; 1298 } catch (ClassCastException e) { 1299 typeWarning(key, o, "ArrayList<String>", e); 1300 return null; 1301 } 1302 } 1303 1304 /** 1305 * Returns the value associated with the given key, or null if 1306 * no mapping of the desired type exists for the given key or a null 1307 * value is explicitly associated with the key. 1308 * 1309 * @param key a String, or null 1310 * @return an ArrayList<CharSequence> value, or null 1311 */ getCharSequenceArrayList(String key)1312 public ArrayList<CharSequence> getCharSequenceArrayList(String key) { 1313 unparcel(); 1314 Object o = mMap.get(key); 1315 if (o == null) { 1316 return null; 1317 } 1318 try { 1319 return (ArrayList<CharSequence>) o; 1320 } catch (ClassCastException e) { 1321 typeWarning(key, o, "ArrayList<CharSequence>", e); 1322 return null; 1323 } 1324 } 1325 1326 /** 1327 * Returns the value associated with the given key, or null if 1328 * no mapping of the desired type exists for the given key or a null 1329 * value is explicitly associated with the key. 1330 * 1331 * @param key a String, or null 1332 * @return a boolean[] value, or null 1333 */ getBooleanArray(String key)1334 public boolean[] getBooleanArray(String key) { 1335 unparcel(); 1336 Object o = mMap.get(key); 1337 if (o == null) { 1338 return null; 1339 } 1340 try { 1341 return (boolean[]) o; 1342 } catch (ClassCastException e) { 1343 typeWarning(key, o, "byte[]", e); 1344 return null; 1345 } 1346 } 1347 1348 /** 1349 * Returns the value associated with the given key, or null if 1350 * no mapping of the desired type exists for the given key or a null 1351 * value is explicitly associated with the key. 1352 * 1353 * @param key a String, or null 1354 * @return a byte[] value, or null 1355 */ getByteArray(String key)1356 public byte[] getByteArray(String key) { 1357 unparcel(); 1358 Object o = mMap.get(key); 1359 if (o == null) { 1360 return null; 1361 } 1362 try { 1363 return (byte[]) o; 1364 } catch (ClassCastException e) { 1365 typeWarning(key, o, "byte[]", e); 1366 return null; 1367 } 1368 } 1369 1370 /** 1371 * Returns the value associated with the given key, or null if 1372 * no mapping of the desired type exists for the given key or a null 1373 * value is explicitly associated with the key. 1374 * 1375 * @param key a String, or null 1376 * @return a short[] value, or null 1377 */ getShortArray(String key)1378 public short[] getShortArray(String key) { 1379 unparcel(); 1380 Object o = mMap.get(key); 1381 if (o == null) { 1382 return null; 1383 } 1384 try { 1385 return (short[]) o; 1386 } catch (ClassCastException e) { 1387 typeWarning(key, o, "short[]", e); 1388 return null; 1389 } 1390 } 1391 1392 /** 1393 * Returns the value associated with the given key, or null if 1394 * no mapping of the desired type exists for the given key or a null 1395 * value is explicitly associated with the key. 1396 * 1397 * @param key a String, or null 1398 * @return a char[] value, or null 1399 */ getCharArray(String key)1400 public char[] getCharArray(String key) { 1401 unparcel(); 1402 Object o = mMap.get(key); 1403 if (o == null) { 1404 return null; 1405 } 1406 try { 1407 return (char[]) o; 1408 } catch (ClassCastException e) { 1409 typeWarning(key, o, "char[]", e); 1410 return null; 1411 } 1412 } 1413 1414 /** 1415 * Returns the value associated with the given key, or null if 1416 * no mapping of the desired type exists for the given key or a null 1417 * value is explicitly associated with the key. 1418 * 1419 * @param key a String, or null 1420 * @return an int[] value, or null 1421 */ getIntArray(String key)1422 public int[] getIntArray(String key) { 1423 unparcel(); 1424 Object o = mMap.get(key); 1425 if (o == null) { 1426 return null; 1427 } 1428 try { 1429 return (int[]) o; 1430 } catch (ClassCastException e) { 1431 typeWarning(key, o, "int[]", e); 1432 return null; 1433 } 1434 } 1435 1436 /** 1437 * Returns the value associated with the given key, or null if 1438 * no mapping of the desired type exists for the given key or a null 1439 * value is explicitly associated with the key. 1440 * 1441 * @param key a String, or null 1442 * @return a long[] value, or null 1443 */ getLongArray(String key)1444 public long[] getLongArray(String key) { 1445 unparcel(); 1446 Object o = mMap.get(key); 1447 if (o == null) { 1448 return null; 1449 } 1450 try { 1451 return (long[]) o; 1452 } catch (ClassCastException e) { 1453 typeWarning(key, o, "long[]", e); 1454 return null; 1455 } 1456 } 1457 1458 /** 1459 * Returns the value associated with the given key, or null if 1460 * no mapping of the desired type exists for the given key or a null 1461 * value is explicitly associated with the key. 1462 * 1463 * @param key a String, or null 1464 * @return a float[] value, or null 1465 */ getFloatArray(String key)1466 public float[] getFloatArray(String key) { 1467 unparcel(); 1468 Object o = mMap.get(key); 1469 if (o == null) { 1470 return null; 1471 } 1472 try { 1473 return (float[]) o; 1474 } catch (ClassCastException e) { 1475 typeWarning(key, o, "float[]", e); 1476 return null; 1477 } 1478 } 1479 1480 /** 1481 * Returns the value associated with the given key, or null if 1482 * no mapping of the desired type exists for the given key or a null 1483 * value is explicitly associated with the key. 1484 * 1485 * @param key a String, or null 1486 * @return a double[] value, or null 1487 */ getDoubleArray(String key)1488 public double[] getDoubleArray(String key) { 1489 unparcel(); 1490 Object o = mMap.get(key); 1491 if (o == null) { 1492 return null; 1493 } 1494 try { 1495 return (double[]) o; 1496 } catch (ClassCastException e) { 1497 typeWarning(key, o, "double[]", e); 1498 return null; 1499 } 1500 } 1501 1502 /** 1503 * Returns the value associated with the given key, or null if 1504 * no mapping of the desired type exists for the given key or a null 1505 * value is explicitly associated with the key. 1506 * 1507 * @param key a String, or null 1508 * @return a String[] value, or null 1509 */ getStringArray(String key)1510 public String[] getStringArray(String key) { 1511 unparcel(); 1512 Object o = mMap.get(key); 1513 if (o == null) { 1514 return null; 1515 } 1516 try { 1517 return (String[]) o; 1518 } catch (ClassCastException e) { 1519 typeWarning(key, o, "String[]", e); 1520 return null; 1521 } 1522 } 1523 1524 /** 1525 * Returns the value associated with the given key, or null if 1526 * no mapping of the desired type exists for the given key or a null 1527 * value is explicitly associated with the key. 1528 * 1529 * @param key a String, or null 1530 * @return a CharSequence[] value, or null 1531 */ getCharSequenceArray(String key)1532 public CharSequence[] getCharSequenceArray(String key) { 1533 unparcel(); 1534 Object o = mMap.get(key); 1535 if (o == null) { 1536 return null; 1537 } 1538 try { 1539 return (CharSequence[]) o; 1540 } catch (ClassCastException e) { 1541 typeWarning(key, o, "CharSequence[]", e); 1542 return null; 1543 } 1544 } 1545 1546 /** 1547 * Returns the value associated with the given key, or null if 1548 * no mapping of the desired type exists for the given key or a null 1549 * value is explicitly associated with the key. 1550 * 1551 * @param key a String, or null 1552 * @return an IBinder value, or null 1553 * 1554 * @deprecated 1555 * @hide 1556 */ 1557 @Deprecated getIBinder(String key)1558 public IBinder getIBinder(String key) { 1559 unparcel(); 1560 Object o = mMap.get(key); 1561 if (o == null) { 1562 return null; 1563 } 1564 try { 1565 return (IBinder) o; 1566 } catch (ClassCastException e) { 1567 typeWarning(key, o, "IBinder", e); 1568 return null; 1569 } 1570 } 1571 1572 public static final Parcelable.Creator<Bundle> CREATOR = 1573 new Parcelable.Creator<Bundle>() { 1574 public Bundle createFromParcel(Parcel in) { 1575 return in.readBundle(); 1576 } 1577 1578 public Bundle[] newArray(int size) { 1579 return new Bundle[size]; 1580 } 1581 }; 1582 1583 /** 1584 * Report the nature of this Parcelable's contents 1585 */ describeContents()1586 public int describeContents() { 1587 int mask = 0; 1588 if (hasFileDescriptors()) { 1589 mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR; 1590 } 1591 return mask; 1592 } 1593 1594 /** 1595 * Writes the Bundle contents to a Parcel, typically in order for 1596 * it to be passed through an IBinder connection. 1597 * @param parcel The parcel to copy this bundle to. 1598 */ writeToParcel(Parcel parcel, int flags)1599 public void writeToParcel(Parcel parcel, int flags) { 1600 final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds); 1601 try { 1602 if (mParcelledData != null) { 1603 int length = mParcelledData.dataSize(); 1604 parcel.writeInt(length); 1605 parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L' 1606 parcel.appendFrom(mParcelledData, 0, length); 1607 } else { 1608 parcel.writeInt(-1); // dummy, will hold length 1609 parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L' 1610 1611 int oldPos = parcel.dataPosition(); 1612 parcel.writeMapInternal(mMap); 1613 int newPos = parcel.dataPosition(); 1614 1615 // Backpatch length 1616 parcel.setDataPosition(oldPos - 8); 1617 int length = newPos - oldPos; 1618 parcel.writeInt(length); 1619 parcel.setDataPosition(newPos); 1620 } 1621 } finally { 1622 parcel.restoreAllowFds(oldAllowFds); 1623 } 1624 } 1625 1626 /** 1627 * Reads the Parcel contents into this Bundle, typically in order for 1628 * it to be passed through an IBinder connection. 1629 * @param parcel The parcel to overwrite this bundle from. 1630 */ readFromParcel(Parcel parcel)1631 public void readFromParcel(Parcel parcel) { 1632 int length = parcel.readInt(); 1633 if (length < 0) { 1634 throw new RuntimeException("Bad length in parcel: " + length); 1635 } 1636 readFromParcelInner(parcel, length); 1637 } 1638 readFromParcelInner(Parcel parcel, int length)1639 void readFromParcelInner(Parcel parcel, int length) { 1640 int magic = parcel.readInt(); 1641 if (magic != 0x4C444E42) { 1642 //noinspection ThrowableInstanceNeverThrown 1643 String st = Log.getStackTraceString(new RuntimeException()); 1644 Log.e("Bundle", "readBundle: bad magic number"); 1645 Log.e("Bundle", "readBundle: trace = " + st); 1646 } 1647 1648 // Advance within this Parcel 1649 int offset = parcel.dataPosition(); 1650 parcel.setDataPosition(offset + length); 1651 1652 Parcel p = Parcel.obtain(); 1653 p.setDataPosition(0); 1654 p.appendFrom(parcel, offset, length); 1655 p.setDataPosition(0); 1656 1657 mParcelledData = p; 1658 mHasFds = p.hasFileDescriptors(); 1659 mFdsKnown = true; 1660 } 1661 1662 @Override toString()1663 public synchronized String toString() { 1664 if (mParcelledData != null) { 1665 return "Bundle[mParcelledData.dataSize=" + 1666 mParcelledData.dataSize() + "]"; 1667 } 1668 return "Bundle[" + mMap.toString() + "]"; 1669 } 1670 } 1671