2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import android.annotation.Nullable;
20 import android.util.ArrayMap;
21 import android.util.Size;
22 import android.util.SizeF;
23 import android.util.SparseArray;
25 import java.io.Serializable;
26 import java.util.ArrayList;
27 import java.util.List;
30 * A mapping from String values to various Parcelable types.
33 public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
34 public static final Bundle EMPTY;
35 static final Parcel EMPTY_PARCEL;
39 EMPTY.mMap = ArrayMap.EMPTY;
40 EMPTY_PARCEL = BaseBundle.EMPTY_PARCEL;
43 private boolean mHasFds = false;
44 private boolean mFdsKnown = true;
45 private boolean mAllowFds = true;
48 * Constructs a new, empty Bundle.
55 * Constructs a Bundle whose data is stored as a Parcel. The data
56 * will be unparcelled on first contact, using the assigned ClassLoader.
58 * @param parcelledData a Parcel containing a Bundle
60 Bundle(Parcel parcelledData) {
63 mHasFds = mParcelledData.hasFileDescriptors();
67 /* package */ Bundle(Parcel parcelledData, int length) {
68 super(parcelledData, length);
70 mHasFds = mParcelledData.hasFileDescriptors();
75 * Constructs a new, empty Bundle that uses a specific ClassLoader for
76 * instantiating Parcelable and Serializable objects.
78 * @param loader An explicit ClassLoader to use when instantiating objects
79 * inside of the Bundle.
81 public Bundle(ClassLoader loader) {
86 * Constructs a new, empty Bundle sized to hold the given number of
87 * elements. The Bundle will grow as needed.
89 * @param capacity the initial capacity of the Bundle
91 public Bundle(int capacity) {
96 * Constructs a Bundle containing a copy of the mappings from the given
99 * @param b a Bundle to be copied.
101 public Bundle(Bundle b) {
105 mFdsKnown = b.mFdsKnown;
109 * Constructs a Bundle containing a copy of the mappings from the given
112 * @param b a Bundle to be copied.
114 public Bundle(PersistableBundle b) {
119 * Make a Bundle for a single key/value pair.
123 public static Bundle forPair(String key, String value) {
124 Bundle b = new Bundle(1);
125 b.putString(key, value);
130 * Changes the ClassLoader this Bundle uses when instantiating objects.
132 * @param loader An explicit ClassLoader to use when instantiating objects
133 * inside of the Bundle.
136 public void setClassLoader(ClassLoader loader) {
137 super.setClassLoader(loader);
141 * Return the ClassLoader currently associated with this Bundle.
144 public ClassLoader getClassLoader() {
145 return super.getClassLoader();
149 public boolean setAllowFds(boolean allowFds) {
150 boolean orig = mAllowFds;
151 mAllowFds = allowFds;
156 * Clones the current Bundle. The internal map is cloned, but the keys and
157 * values to which it refers are copied by reference.
160 public Object clone() {
161 return new Bundle(this);
165 * Removes all elements from the mapping of this Bundle.
168 public void clear() {
176 * Inserts all mappings from the given Bundle into this Bundle.
178 * @param bundle a Bundle
180 public void putAll(Bundle bundle) {
183 mMap.putAll(bundle.mMap);
185 // fd state is now known if and only if both bundles already knew
186 mHasFds |= bundle.mHasFds;
187 mFdsKnown = mFdsKnown && bundle.mFdsKnown;
191 * Reports whether the bundle contains any parcelled file descriptors.
193 public boolean hasFileDescriptors() {
195 boolean fdFound = false; // keep going until we find one or run out of data
197 if (mParcelledData != null) {
198 if (mParcelledData.hasFileDescriptors()) {
202 // It's been unparcelled, so we need to walk the map
203 for (int i=mMap.size()-1; i>=0; i--) {
204 Object obj = mMap.valueAt(i);
205 if (obj instanceof Parcelable) {
206 if ((((Parcelable)obj).describeContents()
207 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
211 } else if (obj instanceof Parcelable[]) {
212 Parcelable[] array = (Parcelable[]) obj;
213 for (int n = array.length - 1; n >= 0; n--) {
214 Parcelable p = array[n];
215 if (p != null && ((p.describeContents()
216 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
221 } else if (obj instanceof SparseArray) {
222 SparseArray<? extends Parcelable> array =
223 (SparseArray<? extends Parcelable>) obj;
224 for (int n = array.size() - 1; n >= 0; n--) {
225 Parcelable p = array.valueAt(n);
226 if (p != null && (p.describeContents()
227 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
232 } else if (obj instanceof ArrayList) {
233 ArrayList array = (ArrayList) obj;
234 // an ArrayList here might contain either Strings or
235 // Parcelables; only look inside for Parcelables
236 if (!array.isEmpty() && (array.get(0) instanceof Parcelable)) {
237 for (int n = array.size() - 1; n >= 0; n--) {
238 Parcelable p = (Parcelable) array.get(n);
239 if (p != null && ((p.describeContents()
240 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
257 * Filter values in Bundle to only basic types.
260 public void filterValues() {
263 for (int i = mMap.size() - 1; i >= 0; i--) {
264 Object value = mMap.valueAt(i);
265 if (PersistableBundle.isValidType(value)) {
268 if (value instanceof Bundle) {
269 ((Bundle)value).filterValues();
271 if (value.getClass().getName().startsWith("android.")) {
280 * Inserts a byte value into the mapping of this Bundle, replacing
281 * any existing value for the given key.
283 * @param key a String, or null
284 * @param value a byte
287 public void putByte(@Nullable String key, byte value) {
288 super.putByte(key, value);
292 * Inserts a char value into the mapping of this Bundle, replacing
293 * any existing value for the given key.
295 * @param key a String, or null
296 * @param value a char
299 public void putChar(@Nullable String key, char value) {
300 super.putChar(key, value);
304 * Inserts a short value into the mapping of this Bundle, replacing
305 * any existing value for the given key.
307 * @param key a String, or null
308 * @param value a short
311 public void putShort(@Nullable String key, short value) {
312 super.putShort(key, value);
316 * Inserts a float value into the mapping of this Bundle, replacing
317 * any existing value for the given key.
319 * @param key a String, or null
320 * @param value a float
323 public void putFloat(@Nullable String key, float value) {
324 super.putFloat(key, value);
328 * Inserts a CharSequence value into the mapping of this Bundle, replacing
329 * any existing value for the given key. Either key or value may be null.
331 * @param key a String, or null
332 * @param value a CharSequence, or null
335 public void putCharSequence(@Nullable String key, @Nullable CharSequence value) {
336 super.putCharSequence(key, value);
340 * Inserts a Parcelable value into the mapping of this Bundle, replacing
341 * any existing value for the given key. Either key or value may be null.
343 * @param key a String, or null
344 * @param value a Parcelable object, or null
346 public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
348 mMap.put(key, value);
353 * Inserts a Size value into the mapping of this Bundle, replacing
354 * any existing value for the given key. Either key or value may be null.
356 * @param key a String, or null
357 * @param value a Size object, or null
359 public void putSize(@Nullable String key, @Nullable Size value) {
361 mMap.put(key, value);
365 * Inserts a SizeF value into the mapping of this Bundle, replacing
366 * any existing value for the given key. Either key or value may be null.
368 * @param key a String, or null
369 * @param value a SizeF object, or null
371 public void putSizeF(@Nullable String key, @Nullable SizeF value) {
373 mMap.put(key, value);
377 * Inserts an array of Parcelable values into the mapping of this Bundle,
378 * replacing any existing value for the given key. Either key or value may
381 * @param key a String, or null
382 * @param value an array of Parcelable objects, or null
384 public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
386 mMap.put(key, value);
391 * Inserts a List of Parcelable values into the mapping of this Bundle,
392 * replacing any existing value for the given key. Either key or value may
395 * @param key a String, or null
396 * @param value an ArrayList of Parcelable objects, or null
398 public void putParcelableArrayList(@Nullable String key,
399 @Nullable ArrayList<? extends Parcelable> value) {
401 mMap.put(key, value);
406 public void putParcelableList(String key, List<? extends Parcelable> value) {
408 mMap.put(key, value);
413 * Inserts a SparceArray of Parcelable values into the mapping of this
414 * Bundle, replacing any existing value for the given key. Either key
415 * or value may be null.
417 * @param key a String, or null
418 * @param value a SparseArray of Parcelable objects, or null
420 public void putSparseParcelableArray(@Nullable String key,
421 @Nullable SparseArray<? extends Parcelable> value) {
423 mMap.put(key, value);
428 * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
429 * any existing value for the given key. Either key or value may be null.
431 * @param key a String, or null
432 * @param value an ArrayList<Integer> object, or null
435 public void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
436 super.putIntegerArrayList(key, value);
440 * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
441 * any existing value for the given key. Either key or value may be null.
443 * @param key a String, or null
444 * @param value an ArrayList<String> object, or null
447 public void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
448 super.putStringArrayList(key, value);
452 * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
453 * any existing value for the given key. Either key or value may be null.
455 * @param key a String, or null
456 * @param value an ArrayList<CharSequence> object, or null
459 public void putCharSequenceArrayList(@Nullable String key,
460 @Nullable ArrayList<CharSequence> value) {
461 super.putCharSequenceArrayList(key, value);
465 * Inserts a Serializable value into the mapping of this Bundle, replacing
466 * any existing value for the given key. Either key or value may be null.
468 * @param key a String, or null
469 * @param value a Serializable object, or null
472 public void putSerializable(@Nullable String key, @Nullable Serializable value) {
473 super.putSerializable(key, value);
477 * Inserts a byte array value into the mapping of this Bundle, replacing
478 * any existing value for the given key. Either key or value may be null.
480 * @param key a String, or null
481 * @param value a byte array object, or null
484 public void putByteArray(@Nullable String key, @Nullable byte[] value) {
485 super.putByteArray(key, value);
489 * Inserts a short array value into the mapping of this Bundle, replacing
490 * any existing value for the given key. Either key or value may be null.
492 * @param key a String, or null
493 * @param value a short array object, or null
496 public void putShortArray(@Nullable String key, @Nullable short[] value) {
497 super.putShortArray(key, value);
501 * Inserts a char array value into the mapping of this Bundle, replacing
502 * any existing value for the given key. Either key or value may be null.
504 * @param key a String, or null
505 * @param value a char array object, or null
508 public void putCharArray(@Nullable String key, @Nullable char[] value) {
509 super.putCharArray(key, value);
513 * Inserts a float array value into the mapping of this Bundle, replacing
514 * any existing value for the given key. Either key or value may be null.
516 * @param key a String, or null
517 * @param value a float array object, or null
520 public void putFloatArray(@Nullable String key, @Nullable float[] value) {
521 super.putFloatArray(key, value);
525 * Inserts a CharSequence array value into the mapping of this Bundle, replacing
526 * any existing value for the given key. Either key or value may be null.
528 * @param key a String, or null
529 * @param value a CharSequence array object, or null
532 public void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
533 super.putCharSequenceArray(key, value);
537 * Inserts a Bundle value into the mapping of this Bundle, replacing
538 * any existing value for the given key. Either key or value may be null.
540 * @param key a String, or null
541 * @param value a Bundle object, or null
543 public void putBundle(@Nullable String key, @Nullable Bundle value) {
545 mMap.put(key, value);
549 * Inserts an {@link IBinder} value into the mapping of this Bundle, replacing
550 * any existing value for the given key. Either key or value may be null.
552 * <p class="note">You should be very careful when using this function. In many
553 * places where Bundles are used (such as inside of Intent objects), the Bundle
554 * can live longer inside of another process than the process that had originally
555 * created it. In that case, the IBinder you supply here will become invalid
556 * when your process goes away, and no longer usable, even if a new process is
557 * created for you later on.</p>
559 * @param key a String, or null
560 * @param value an IBinder object, or null
562 public void putBinder(@Nullable String key, @Nullable IBinder value) {
564 mMap.put(key, value);
568 * Inserts an IBinder value into the mapping of this Bundle, replacing
569 * any existing value for the given key. Either key or value may be null.
571 * @param key a String, or null
572 * @param value an IBinder object, or null
575 * @hide This is the old name of the function.
578 public void putIBinder(@Nullable String key, @Nullable IBinder value) {
580 mMap.put(key, value);
584 * Returns the value associated with the given key, or (byte) 0 if
585 * no mapping of the desired type exists for the given key.
587 * @param key a String
588 * @return a byte value
591 public byte getByte(String key) {
592 return super.getByte(key);
596 * Returns the value associated with the given key, or defaultValue if
597 * no mapping of the desired type exists for the given key.
599 * @param key a String
600 * @param defaultValue Value to return if key does not exist
601 * @return a byte value
604 public Byte getByte(String key, byte defaultValue) {
605 return super.getByte(key, defaultValue);
609 * Returns the value associated with the given key, or (char) 0 if
610 * no mapping of the desired type exists for the given key.
612 * @param key a String
613 * @return a char value
616 public char getChar(String key) {
617 return super.getChar(key);
621 * Returns the value associated with the given key, or defaultValue if
622 * no mapping of the desired type exists for the given key.
624 * @param key a String
625 * @param defaultValue Value to return if key does not exist
626 * @return a char value
629 public char getChar(String key, char defaultValue) {
630 return super.getChar(key, defaultValue);
634 * Returns the value associated with the given key, or (short) 0 if
635 * no mapping of the desired type exists for the given key.
637 * @param key a String
638 * @return a short value
641 public short getShort(String key) {
642 return super.getShort(key);
646 * Returns the value associated with the given key, or defaultValue if
647 * no mapping of the desired type exists for the given key.
649 * @param key a String
650 * @param defaultValue Value to return if key does not exist
651 * @return a short value
654 public short getShort(String key, short defaultValue) {
655 return super.getShort(key, defaultValue);
659 * Returns the value associated with the given key, or 0.0f if
660 * no mapping of the desired type exists for the given key.
662 * @param key a String
663 * @return a float value
666 public float getFloat(String key) {
667 return super.getFloat(key);
671 * Returns the value associated with the given key, or defaultValue if
672 * no mapping of the desired type exists for the given key.
674 * @param key a String
675 * @param defaultValue Value to return if key does not exist
676 * @return a float value
679 public float getFloat(String key, float defaultValue) {
680 return super.getFloat(key, defaultValue);
684 * Returns the value associated with the given key, or null if
685 * no mapping of the desired type exists for the given key or a null
686 * value is explicitly associated with the key.
688 * @param key a String, or null
689 * @return a CharSequence value, or null
693 public CharSequence getCharSequence(@Nullable String key) {
694 return super.getCharSequence(key);
698 * Returns the value associated with the given key, or defaultValue if
699 * no mapping of the desired type exists for the given key or if a null
700 * value is explicitly associatd with the given key.
702 * @param key a String, or null
703 * @param defaultValue Value to return if key does not exist or if a null
704 * value is associated with the given key.
705 * @return the CharSequence value associated with the given key, or defaultValue
706 * if no valid CharSequence object is currently mapped to that key.
709 public CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) {
710 return super.getCharSequence(key, defaultValue);
714 * Returns the value associated with the given key, or null if
715 * no mapping of the desired type exists for the given key or a null
716 * value is explicitly associated with the key.
718 * @param key a String, or null
719 * @return a Size value, or null
722 public Size getSize(@Nullable String key) {
724 final Object o = mMap.get(key);
727 } catch (ClassCastException e) {
728 typeWarning(key, o, "Size", e);
734 * Returns the value associated with the given key, or null if
735 * no mapping of the desired type exists for the given key or a null
736 * value is explicitly associated with the key.
738 * @param key a String, or null
739 * @return a Size value, or null
742 public SizeF getSizeF(@Nullable String key) {
744 final Object o = mMap.get(key);
747 } catch (ClassCastException e) {
748 typeWarning(key, o, "SizeF", e);
754 * Returns the value associated with the given key, or null if
755 * no mapping of the desired type exists for the given key or a null
756 * value is explicitly associated with the key.
758 * @param key a String, or null
759 * @return a Bundle value, or null
762 public Bundle getBundle(@Nullable String key) {
764 Object o = mMap.get(key);
770 } catch (ClassCastException e) {
771 typeWarning(key, o, "Bundle", e);
777 * Returns the value associated with the given key, or null if
778 * no mapping of the desired type exists for the given key or a null
779 * value is explicitly associated with the key.
781 * @param key a String, or null
782 * @return a Parcelable value, or null
785 public <T extends Parcelable> T getParcelable(@Nullable String key) {
787 Object o = mMap.get(key);
793 } catch (ClassCastException e) {
794 typeWarning(key, o, "Parcelable", e);
800 * Returns the value associated with the given key, or null if
801 * no mapping of the desired type exists for the given key or a null
802 * value is explicitly associated with the key.
804 * @param key a String, or null
805 * @return a Parcelable[] value, or null
808 public Parcelable[] getParcelableArray(@Nullable String key) {
810 Object o = mMap.get(key);
815 return (Parcelable[]) o;
816 } catch (ClassCastException e) {
817 typeWarning(key, o, "Parcelable[]", e);
823 * Returns the value associated with the given key, or null if
824 * no mapping of the desired type exists for the given key or a null
825 * value is explicitly associated with the key.
827 * @param key a String, or null
828 * @return an ArrayList<T> value, or null
831 public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) {
833 Object o = mMap.get(key);
838 return (ArrayList<T>) o;
839 } catch (ClassCastException e) {
840 typeWarning(key, o, "ArrayList", e);
846 * Returns the value associated with the given key, or null if
847 * no mapping of the desired type exists for the given key or a null
848 * value is explicitly associated with the key.
850 * @param key a String, or null
852 * @return a SparseArray of T values, or null
855 public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(@Nullable String key) {
857 Object o = mMap.get(key);
862 return (SparseArray<T>) o;
863 } catch (ClassCastException e) {
864 typeWarning(key, o, "SparseArray", e);
870 * Returns the value associated with the given key, or null if
871 * no mapping of the desired type exists for the given key or a null
872 * value is explicitly associated with the key.
874 * @param key a String, or null
875 * @return a Serializable value, or null
879 public Serializable getSerializable(@Nullable String key) {
880 return super.getSerializable(key);
884 * Returns the value associated with the given key, or null if
885 * no mapping of the desired type exists for the given key or a null
886 * value is explicitly associated with the key.
888 * @param key a String, or null
889 * @return an ArrayList<String> value, or null
893 public ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
894 return super.getIntegerArrayList(key);
898 * Returns the value associated with the given key, or null if
899 * no mapping of the desired type exists for the given key or a null
900 * value is explicitly associated with the key.
902 * @param key a String, or null
903 * @return an ArrayList<String> value, or null
907 public ArrayList<String> getStringArrayList(@Nullable String key) {
908 return super.getStringArrayList(key);
912 * Returns the value associated with the given key, or null if
913 * no mapping of the desired type exists for the given key or a null
914 * value is explicitly associated with the key.
916 * @param key a String, or null
917 * @return an ArrayList<CharSequence> value, or null
921 public ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) {
922 return super.getCharSequenceArrayList(key);
926 * Returns the value associated with the given key, or null if
927 * no mapping of the desired type exists for the given key or a null
928 * value is explicitly associated with the key.
930 * @param key a String, or null
931 * @return a byte[] value, or null
935 public byte[] getByteArray(@Nullable String key) {
936 return super.getByteArray(key);
940 * Returns the value associated with the given key, or null if
941 * no mapping of the desired type exists for the given key or a null
942 * value is explicitly associated with the key.
944 * @param key a String, or null
945 * @return a short[] value, or null
949 public short[] getShortArray(@Nullable String key) {
950 return super.getShortArray(key);
954 * Returns the value associated with the given key, or null if
955 * no mapping of the desired type exists for the given key or a null
956 * value is explicitly associated with the key.
958 * @param key a String, or null
959 * @return a char[] value, or null
963 public char[] getCharArray(@Nullable String key) {
964 return super.getCharArray(key);
968 * Returns the value associated with the given key, or null if
969 * no mapping of the desired type exists for the given key or a null
970 * value is explicitly associated with the key.
972 * @param key a String, or null
973 * @return a float[] value, or null
977 public float[] getFloatArray(@Nullable String key) {
978 return super.getFloatArray(key);
982 * Returns the value associated with the given key, or null if
983 * no mapping of the desired type exists for the given key or a null
984 * value is explicitly associated with the key.
986 * @param key a String, or null
987 * @return a CharSequence[] value, or null
991 public CharSequence[] getCharSequenceArray(@Nullable String key) {
992 return super.getCharSequenceArray(key);
996 * Returns the value associated with the given key, or null if
997 * no mapping of the desired type exists for the given key or a null
998 * value is explicitly associated with the key.
1000 * @param key a String, or null
1001 * @return an IBinder value, or null
1004 public IBinder getBinder(@Nullable String key) {
1006 Object o = mMap.get(key);
1012 } catch (ClassCastException e) {
1013 typeWarning(key, o, "IBinder", e);
1019 * Returns the value associated with the given key, or null if
1020 * no mapping of the desired type exists for the given key or a null
1021 * value is explicitly associated with the key.
1023 * @param key a String, or null
1024 * @return an IBinder value, or null
1027 * @hide This is the old name of the function.
1031 public IBinder getIBinder(@Nullable String key) {
1033 Object o = mMap.get(key);
1039 } catch (ClassCastException e) {
1040 typeWarning(key, o, "IBinder", e);
1045 public static final Parcelable.Creator<Bundle> CREATOR =
1046 new Parcelable.Creator<Bundle>() {
1048 public Bundle createFromParcel(Parcel in) {
1049 return in.readBundle();
1053 public Bundle[] newArray(int size) {
1054 return new Bundle[size];
1059 * Report the nature of this Parcelable's contents
1062 public int describeContents() {
1064 if (hasFileDescriptors()) {
1065 mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
1071 * Writes the Bundle contents to a Parcel, typically in order for
1072 * it to be passed through an IBinder connection.
1073 * @param parcel The parcel to copy this bundle to.
1076 public void writeToParcel(Parcel parcel, int flags) {
1077 final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
1079 super.writeToParcelInner(parcel, flags);
1081 parcel.restoreAllowFds(oldAllowFds);
1086 * Reads the Parcel contents into this Bundle, typically in order for
1087 * it to be passed through an IBinder connection.
1088 * @param parcel The parcel to overwrite this bundle from.
1090 public void readFromParcel(Parcel parcel) {
1091 super.readFromParcelInner(parcel);
1092 mHasFds = mParcelledData.hasFileDescriptors();
1097 public synchronized String toString() {
1098 if (mParcelledData != null) {
1099 if (mParcelledData == EMPTY_PARCEL) {
1100 return "Bundle[EMPTY_PARCEL]";
1102 return "Bundle[mParcelledData.dataSize=" +
1103 mParcelledData.dataSize() + "]";
1106 return "Bundle[" + mMap.toString() + "]";