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