2 * Copyright (C) 2014 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.Log;
22 import android.util.MathUtils;
24 import java.io.Serializable;
25 import java.util.ArrayList;
29 * A mapping from String values to various types.
31 public class BaseBundle {
32 private static final String TAG = "Bundle";
33 static final boolean DEBUG = false;
35 // Keep in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
36 static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
38 static final Parcel EMPTY_PARCEL;
41 EMPTY_PARCEL = Parcel.obtain();
44 // Invariant - exactly one of mMap / mParcelledData will be null
45 // (except inside a call to unparcel)
47 ArrayMap<String, Object> mMap = null;
50 * If mParcelledData is non-null, then mMap will be null and the
51 * data are stored as a Parcel containing a Bundle. When the data
52 * are unparcelled, mParcelledData willbe set to null.
54 Parcel mParcelledData = null;
57 * The ClassLoader used when unparcelling data from mParcelledData.
59 private ClassLoader mClassLoader;
62 * Constructs a new, empty Bundle that uses a specific ClassLoader for
63 * instantiating Parcelable and Serializable objects.
65 * @param loader An explicit ClassLoader to use when instantiating objects
66 * inside of the Bundle.
67 * @param capacity Initial size of the ArrayMap.
69 BaseBundle(@Nullable ClassLoader loader, int capacity) {
71 new ArrayMap<String, Object>(capacity) : new ArrayMap<String, Object>();
72 mClassLoader = loader == null ? getClass().getClassLoader() : loader;
76 * Constructs a new, empty Bundle.
79 this((ClassLoader) null, 0);
83 * Constructs a Bundle whose data is stored as a Parcel. The data
84 * will be unparcelled on first contact, using the assigned ClassLoader.
86 * @param parcelledData a Parcel containing a Bundle
88 BaseBundle(Parcel parcelledData) {
89 readFromParcelInner(parcelledData);
92 BaseBundle(Parcel parcelledData, int length) {
93 readFromParcelInner(parcelledData, length);
97 * Constructs a new, empty Bundle that uses a specific ClassLoader for
98 * instantiating Parcelable and Serializable objects.
100 * @param loader An explicit ClassLoader to use when instantiating objects
101 * inside of the Bundle.
103 BaseBundle(ClassLoader loader) {
108 * Constructs a new, empty Bundle sized to hold the given number of
109 * elements. The Bundle will grow as needed.
111 * @param capacity the initial capacity of the Bundle
113 BaseBundle(int capacity) {
114 this((ClassLoader) null, capacity);
118 * Constructs a Bundle containing a copy of the mappings from the given
121 * @param b a Bundle to be copied.
123 BaseBundle(BaseBundle b) {
124 if (b.mParcelledData != null) {
125 if (b.mParcelledData == EMPTY_PARCEL) {
126 mParcelledData = EMPTY_PARCEL;
128 mParcelledData = Parcel.obtain();
129 mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize());
130 mParcelledData.setDataPosition(0);
133 mParcelledData = null;
136 if (b.mMap != null) {
137 mMap = new ArrayMap<String, Object>(b.mMap);
142 mClassLoader = b.mClassLoader;
146 * TODO: optimize this later (getting just the value part of a Bundle
147 * with a single pair) once Bundle.forPair() above is implemented
148 * with a special single-value Map implementation/serialization.
150 * Note: value in single-pair Bundle may be null.
154 public String getPairValue() {
156 int size = mMap.size();
158 Log.w(TAG, "getPairValue() used on Bundle with multiple pairs.");
163 Object o = mMap.valueAt(0);
166 } catch (ClassCastException e) {
167 typeWarning("getPairValue()", o, "String", e);
173 * Changes the ClassLoader this Bundle uses when instantiating objects.
175 * @param loader An explicit ClassLoader to use when instantiating objects
176 * inside of the Bundle.
178 void setClassLoader(ClassLoader loader) {
179 mClassLoader = loader;
183 * Return the ClassLoader currently associated with this Bundle.
185 ClassLoader getClassLoader() {
190 * If the underlying data are stored as a Parcel, unparcel them
191 * using the currently assigned class loader.
193 /* package */ synchronized void unparcel() {
194 if (mParcelledData == null) {
195 if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
196 + ": no parcelled data");
200 if (mParcelledData == EMPTY_PARCEL) {
201 if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
204 mMap = new ArrayMap<String, Object>(1);
208 mParcelledData = null;
212 int N = mParcelledData.readInt();
213 if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
214 + ": reading " + N + " maps");
219 mMap = new ArrayMap<String, Object>(N);
222 mMap.ensureCapacity(N);
224 mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
225 mParcelledData.recycle();
226 mParcelledData = null;
227 if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
228 + " final map: " + mMap);
234 public boolean isParcelled() {
235 return mParcelledData != null;
239 ArrayMap<String, Object> getMap() {
245 * Returns the number of mappings contained in this Bundle.
247 * @return the number of mappings as an int.
255 * Returns true if the mapping of this Bundle is empty, false otherwise.
257 public boolean isEmpty() {
259 return mMap.isEmpty();
263 * Removes all elements from the mapping of this Bundle.
265 public void clear() {
271 * Returns true if the given key is contained in the mapping
274 * @param key a String key
275 * @return true if the key is part of the mapping, false otherwise
277 public boolean containsKey(String key) {
279 return mMap.containsKey(key);
283 * Returns the entry with the given key as an object.
285 * @param key a String key
286 * @return an Object, or null
289 public Object get(String key) {
291 return mMap.get(key);
295 * Removes any entry with the given key from the mapping of this Bundle.
297 * @param key a String key
299 public void remove(String key) {
305 * Inserts all mappings from the given PersistableBundle into this BaseBundle.
307 * @param bundle a PersistableBundle
309 public void putAll(PersistableBundle bundle) {
312 mMap.putAll(bundle.mMap);
316 * Inserts all mappings from the given Map into this BaseBundle.
320 void putAll(ArrayMap map) {
326 * Returns a Set containing the Strings used as keys in this Bundle.
328 * @return a Set of String keys
330 public Set<String> keySet() {
332 return mMap.keySet();
336 * Inserts a Boolean value into the mapping of this Bundle, replacing
337 * any existing value for the given key. Either key or value may be null.
339 * @param key a String, or null
340 * @param value a boolean
342 public void putBoolean(@Nullable String key, boolean value) {
344 mMap.put(key, value);
348 * Inserts a byte value into the mapping of this Bundle, replacing
349 * any existing value for the given key.
351 * @param key a String, or null
352 * @param value a byte
354 void putByte(@Nullable String key, byte value) {
356 mMap.put(key, value);
360 * Inserts a char value into the mapping of this Bundle, replacing
361 * any existing value for the given key.
363 * @param key a String, or null
364 * @param value a char
366 void putChar(@Nullable String key, char value) {
368 mMap.put(key, value);
372 * Inserts a short value into the mapping of this Bundle, replacing
373 * any existing value for the given key.
375 * @param key a String, or null
376 * @param value a short
378 void putShort(@Nullable String key, short value) {
380 mMap.put(key, value);
384 * Inserts an int value into the mapping of this Bundle, replacing
385 * any existing value for the given key.
387 * @param key a String, or null
388 * @param value an int
390 public void putInt(@Nullable String key, int value) {
392 mMap.put(key, value);
396 * Inserts a long value into the mapping of this Bundle, replacing
397 * any existing value for the given key.
399 * @param key a String, or null
400 * @param value a long
402 public void putLong(@Nullable String key, long value) {
404 mMap.put(key, value);
408 * Inserts a float value into the mapping of this Bundle, replacing
409 * any existing value for the given key.
411 * @param key a String, or null
412 * @param value a float
414 void putFloat(@Nullable String key, float value) {
416 mMap.put(key, value);
420 * Inserts a double value into the mapping of this Bundle, replacing
421 * any existing value for the given key.
423 * @param key a String, or null
424 * @param value a double
426 public void putDouble(@Nullable String key, double value) {
428 mMap.put(key, value);
432 * Inserts a String value into the mapping of this Bundle, replacing
433 * any existing value for the given key. Either key or value may be null.
435 * @param key a String, or null
436 * @param value a String, or null
438 public void putString(@Nullable String key, @Nullable String value) {
440 mMap.put(key, value);
444 * Inserts a CharSequence value into the mapping of this Bundle, replacing
445 * any existing value for the given key. Either key or value may be null.
447 * @param key a String, or null
448 * @param value a CharSequence, or null
450 void putCharSequence(@Nullable String key, @Nullable CharSequence value) {
452 mMap.put(key, value);
456 * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
457 * any existing value for the given key. Either key or value may be null.
459 * @param key a String, or null
460 * @param value an ArrayList<Integer> object, or null
462 void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
464 mMap.put(key, value);
468 * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
469 * any existing value for the given key. Either key or value may be null.
471 * @param key a String, or null
472 * @param value an ArrayList<String> object, or null
474 void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
476 mMap.put(key, value);
480 * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
481 * any existing value for the given key. Either key or value may be null.
483 * @param key a String, or null
484 * @param value an ArrayList<CharSequence> object, or null
486 void putCharSequenceArrayList(@Nullable String key, @Nullable ArrayList<CharSequence> value) {
488 mMap.put(key, value);
492 * Inserts a Serializable value into the mapping of this Bundle, replacing
493 * any existing value for the given key. Either key or value may be null.
495 * @param key a String, or null
496 * @param value a Serializable object, or null
498 void putSerializable(@Nullable String key, @Nullable Serializable value) {
500 mMap.put(key, value);
504 * Inserts a boolean array value into the mapping of this Bundle, replacing
505 * any existing value for the given key. Either key or value may be null.
507 * @param key a String, or null
508 * @param value a boolean array object, or null
510 public void putBooleanArray(@Nullable String key, @Nullable boolean[] value) {
512 mMap.put(key, value);
516 * Inserts a byte array value into the mapping of this Bundle, replacing
517 * any existing value for the given key. Either key or value may be null.
519 * @param key a String, or null
520 * @param value a byte array object, or null
522 void putByteArray(@Nullable String key, @Nullable byte[] value) {
524 mMap.put(key, value);
528 * Inserts a short array value into the mapping of this Bundle, replacing
529 * any existing value for the given key. Either key or value may be null.
531 * @param key a String, or null
532 * @param value a short array object, or null
534 void putShortArray(@Nullable String key, @Nullable short[] value) {
536 mMap.put(key, value);
540 * Inserts a char array value into the mapping of this Bundle, replacing
541 * any existing value for the given key. Either key or value may be null.
543 * @param key a String, or null
544 * @param value a char array object, or null
546 void putCharArray(@Nullable String key, @Nullable char[] value) {
548 mMap.put(key, value);
552 * Inserts an int array value into the mapping of this Bundle, replacing
553 * any existing value for the given key. Either key or value may be null.
555 * @param key a String, or null
556 * @param value an int array object, or null
558 public void putIntArray(@Nullable String key, @Nullable int[] value) {
560 mMap.put(key, value);
564 * Inserts a long array value into the mapping of this Bundle, replacing
565 * any existing value for the given key. Either key or value may be null.
567 * @param key a String, or null
568 * @param value a long array object, or null
570 public void putLongArray(@Nullable String key, @Nullable long[] value) {
572 mMap.put(key, value);
576 * Inserts a float array value into the mapping of this Bundle, replacing
577 * any existing value for the given key. Either key or value may be null.
579 * @param key a String, or null
580 * @param value a float array object, or null
582 void putFloatArray(@Nullable String key, @Nullable float[] value) {
584 mMap.put(key, value);
588 * Inserts a double array value into the mapping of this Bundle, replacing
589 * any existing value for the given key. Either key or value may be null.
591 * @param key a String, or null
592 * @param value a double array object, or null
594 public void putDoubleArray(@Nullable String key, @Nullable double[] value) {
596 mMap.put(key, value);
600 * Inserts a String array value into the mapping of this Bundle, replacing
601 * any existing value for the given key. Either key or value may be null.
603 * @param key a String, or null
604 * @param value a String array object, or null
606 public void putStringArray(@Nullable String key, @Nullable String[] value) {
608 mMap.put(key, value);
612 * Inserts a CharSequence array value into the mapping of this Bundle, replacing
613 * any existing value for the given key. Either key or value may be null.
615 * @param key a String, or null
616 * @param value a CharSequence array object, or null
618 void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
620 mMap.put(key, value);
624 * Returns the value associated with the given key, or false if
625 * no mapping of the desired type exists for the given key.
627 * @param key a String
628 * @return a boolean value
630 public boolean getBoolean(String key) {
632 if (DEBUG) Log.d(TAG, "Getting boolean in "
633 + Integer.toHexString(System.identityHashCode(this)));
634 return getBoolean(key, false);
637 // Log a message if the value was non-null but not of the expected type
638 void typeWarning(String key, Object value, String className,
639 Object defaultValue, ClassCastException e) {
640 StringBuilder sb = new StringBuilder();
643 sb.append(" expected ");
644 sb.append(className);
645 sb.append(" but value was a ");
646 sb.append(value.getClass().getName());
647 sb.append(". The default value ");
648 sb.append(defaultValue);
649 sb.append(" was returned.");
650 Log.w(TAG, sb.toString());
651 Log.w(TAG, "Attempt to cast generated internal exception:", e);
654 void typeWarning(String key, Object value, String className,
655 ClassCastException e) {
656 typeWarning(key, value, className, "<null>", e);
660 * Returns the value associated with the given key, or defaultValue if
661 * no mapping of the desired type exists for the given key.
663 * @param key a String
664 * @param defaultValue Value to return if key does not exist
665 * @return a boolean value
667 public boolean getBoolean(String key, boolean defaultValue) {
669 Object o = mMap.get(key);
675 } catch (ClassCastException e) {
676 typeWarning(key, o, "Boolean", defaultValue, e);
682 * Returns the value associated with the given key, or (byte) 0 if
683 * no mapping of the desired type exists for the given key.
685 * @param key a String
686 * @return a byte value
688 byte getByte(String key) {
690 return getByte(key, (byte) 0);
694 * Returns the value associated with the given key, or defaultValue if
695 * no mapping of the desired type exists for the given key.
697 * @param key a String
698 * @param defaultValue Value to return if key does not exist
699 * @return a byte value
701 Byte getByte(String key, byte defaultValue) {
703 Object o = mMap.get(key);
709 } catch (ClassCastException e) {
710 typeWarning(key, o, "Byte", defaultValue, e);
716 * Returns the value associated with the given key, or (char) 0 if
717 * no mapping of the desired type exists for the given key.
719 * @param key a String
720 * @return a char value
722 char getChar(String key) {
724 return getChar(key, (char) 0);
728 * Returns the value associated with the given key, or defaultValue if
729 * no mapping of the desired type exists for the given key.
731 * @param key a String
732 * @param defaultValue Value to return if key does not exist
733 * @return a char value
735 char getChar(String key, char defaultValue) {
737 Object o = mMap.get(key);
742 return (Character) o;
743 } catch (ClassCastException e) {
744 typeWarning(key, o, "Character", defaultValue, e);
750 * Returns the value associated with the given key, or (short) 0 if
751 * no mapping of the desired type exists for the given key.
753 * @param key a String
754 * @return a short value
756 short getShort(String key) {
758 return getShort(key, (short) 0);
762 * Returns the value associated with the given key, or defaultValue if
763 * no mapping of the desired type exists for the given key.
765 * @param key a String
766 * @param defaultValue Value to return if key does not exist
767 * @return a short value
769 short getShort(String key, short defaultValue) {
771 Object o = mMap.get(key);
777 } catch (ClassCastException e) {
778 typeWarning(key, o, "Short", defaultValue, e);
784 * Returns the value associated with the given key, or 0 if
785 * no mapping of the desired type exists for the given key.
787 * @param key a String
788 * @return an int value
790 public int getInt(String key) {
792 return getInt(key, 0);
796 * Returns the value associated with the given key, or defaultValue if
797 * no mapping of the desired type exists for the given key.
799 * @param key a String
800 * @param defaultValue Value to return if key does not exist
801 * @return an int value
803 public int getInt(String key, int defaultValue) {
805 Object o = mMap.get(key);
811 } catch (ClassCastException e) {
812 typeWarning(key, o, "Integer", defaultValue, e);
818 * Returns the value associated with the given key, or 0L if
819 * no mapping of the desired type exists for the given key.
821 * @param key a String
822 * @return a long value
824 public long getLong(String key) {
826 return getLong(key, 0L);
830 * Returns the value associated with the given key, or defaultValue if
831 * no mapping of the desired type exists for the given key.
833 * @param key a String
834 * @param defaultValue Value to return if key does not exist
835 * @return a long value
837 public long getLong(String key, long defaultValue) {
839 Object o = mMap.get(key);
845 } catch (ClassCastException e) {
846 typeWarning(key, o, "Long", defaultValue, e);
852 * Returns the value associated with the given key, or 0.0f if
853 * no mapping of the desired type exists for the given key.
855 * @param key a String
856 * @return a float value
858 float getFloat(String key) {
860 return getFloat(key, 0.0f);
864 * Returns the value associated with the given key, or defaultValue if
865 * no mapping of the desired type exists for the given key.
867 * @param key a String
868 * @param defaultValue Value to return if key does not exist
869 * @return a float value
871 float getFloat(String key, float defaultValue) {
873 Object o = mMap.get(key);
879 } catch (ClassCastException e) {
880 typeWarning(key, o, "Float", defaultValue, e);
886 * Returns the value associated with the given key, or 0.0 if
887 * no mapping of the desired type exists for the given key.
889 * @param key a String
890 * @return a double value
892 public double getDouble(String key) {
894 return getDouble(key, 0.0);
898 * Returns the value associated with the given key, or defaultValue if
899 * no mapping of the desired type exists for the given key.
901 * @param key a String
902 * @param defaultValue Value to return if key does not exist
903 * @return a double value
905 public double getDouble(String key, double defaultValue) {
907 Object o = mMap.get(key);
913 } catch (ClassCastException e) {
914 typeWarning(key, o, "Double", defaultValue, e);
920 * Returns the value associated with the given key, or null if
921 * no mapping of the desired type exists for the given key or a null
922 * value is explicitly associated with the key.
924 * @param key a String, or null
925 * @return a String value, or null
928 public String getString(@Nullable String key) {
930 final Object o = mMap.get(key);
933 } catch (ClassCastException e) {
934 typeWarning(key, o, "String", e);
940 * Returns the value associated with the given key, or defaultValue if
941 * no mapping of the desired type exists for the given key or if a null
942 * value is explicitly associated with the given key.
944 * @param key a String, or null
945 * @param defaultValue Value to return if key does not exist or if a null
946 * value is associated with the given key.
947 * @return the String value associated with the given key, or defaultValue
948 * if no valid String object is currently mapped to that key.
950 public String getString(@Nullable String key, String defaultValue) {
951 final String s = getString(key);
952 return (s == null) ? defaultValue : s;
956 * Returns the value associated with the given key, or null if
957 * no mapping of the desired type exists for the given key or a null
958 * value is explicitly associated with the key.
960 * @param key a String, or null
961 * @return a CharSequence value, or null
964 CharSequence getCharSequence(@Nullable String key) {
966 final Object o = mMap.get(key);
968 return (CharSequence) o;
969 } catch (ClassCastException e) {
970 typeWarning(key, o, "CharSequence", e);
976 * Returns the value associated with the given key, or defaultValue if
977 * no mapping of the desired type exists for the given key or if a null
978 * value is explicitly associated with the given key.
980 * @param key a String, or null
981 * @param defaultValue Value to return if key does not exist or if a null
982 * value is associated with the given key.
983 * @return the CharSequence value associated with the given key, or defaultValue
984 * if no valid CharSequence object is currently mapped to that key.
986 CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) {
987 final CharSequence cs = getCharSequence(key);
988 return (cs == null) ? defaultValue : cs;
992 * Returns the value associated with the given key, or null if
993 * no mapping of the desired type exists for the given key or a null
994 * value is explicitly associated with the key.
996 * @param key a String, or null
997 * @return a Serializable value, or null
1000 Serializable getSerializable(@Nullable String key) {
1002 Object o = mMap.get(key);
1007 return (Serializable) o;
1008 } catch (ClassCastException e) {
1009 typeWarning(key, o, "Serializable", e);
1015 * Returns the value associated with the given key, or null if
1016 * no mapping of the desired type exists for the given key or a null
1017 * value is explicitly associated with the key.
1019 * @param key a String, or null
1020 * @return an ArrayList<String> value, or null
1023 ArrayList<Integer> getIntegerArrayList(@Nullable String key) {
1025 Object o = mMap.get(key);
1030 return (ArrayList<Integer>) o;
1031 } catch (ClassCastException e) {
1032 typeWarning(key, o, "ArrayList<Integer>", e);
1038 * Returns the value associated with the given key, or null if
1039 * no mapping of the desired type exists for the given key or a null
1040 * value is explicitly associated with the key.
1042 * @param key a String, or null
1043 * @return an ArrayList<String> value, or null
1046 ArrayList<String> getStringArrayList(@Nullable String key) {
1048 Object o = mMap.get(key);
1053 return (ArrayList<String>) o;
1054 } catch (ClassCastException e) {
1055 typeWarning(key, o, "ArrayList<String>", e);
1061 * Returns the value associated with the given key, or null if
1062 * no mapping of the desired type exists for the given key or a null
1063 * value is explicitly associated with the key.
1065 * @param key a String, or null
1066 * @return an ArrayList<CharSequence> value, or null
1069 ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) {
1071 Object o = mMap.get(key);
1076 return (ArrayList<CharSequence>) o;
1077 } catch (ClassCastException e) {
1078 typeWarning(key, o, "ArrayList<CharSequence>", e);
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.
1088 * @param key a String, or null
1089 * @return a boolean[] value, or null
1092 public boolean[] getBooleanArray(@Nullable String key) {
1094 Object o = mMap.get(key);
1099 return (boolean[]) o;
1100 } catch (ClassCastException e) {
1101 typeWarning(key, o, "byte[]", e);
1107 * Returns the value associated with the given key, or null if
1108 * no mapping of the desired type exists for the given key or a null
1109 * value is explicitly associated with the key.
1111 * @param key a String, or null
1112 * @return a byte[] value, or null
1115 byte[] getByteArray(@Nullable String key) {
1117 Object o = mMap.get(key);
1123 } catch (ClassCastException e) {
1124 typeWarning(key, o, "byte[]", e);
1130 * Returns the value associated with the given key, or null if
1131 * no mapping of the desired type exists for the given key or a null
1132 * value is explicitly associated with the key.
1134 * @param key a String, or null
1135 * @return a short[] value, or null
1138 short[] getShortArray(@Nullable String key) {
1140 Object o = mMap.get(key);
1146 } catch (ClassCastException e) {
1147 typeWarning(key, o, "short[]", e);
1153 * Returns the value associated with the given key, or null if
1154 * no mapping of the desired type exists for the given key or a null
1155 * value is explicitly associated with the key.
1157 * @param key a String, or null
1158 * @return a char[] value, or null
1161 char[] getCharArray(@Nullable String key) {
1163 Object o = mMap.get(key);
1169 } catch (ClassCastException e) {
1170 typeWarning(key, o, "char[]", e);
1176 * Returns the value associated with the given key, or null if
1177 * no mapping of the desired type exists for the given key or a null
1178 * value is explicitly associated with the key.
1180 * @param key a String, or null
1181 * @return an int[] value, or null
1184 public int[] getIntArray(@Nullable String key) {
1186 Object o = mMap.get(key);
1192 } catch (ClassCastException e) {
1193 typeWarning(key, o, "int[]", e);
1199 * Returns the value associated with the given key, or null if
1200 * no mapping of the desired type exists for the given key or a null
1201 * value is explicitly associated with the key.
1203 * @param key a String, or null
1204 * @return a long[] value, or null
1207 public long[] getLongArray(@Nullable String key) {
1209 Object o = mMap.get(key);
1215 } catch (ClassCastException e) {
1216 typeWarning(key, o, "long[]", e);
1222 * Returns the value associated with the given key, or null if
1223 * no mapping of the desired type exists for the given key or a null
1224 * value is explicitly associated with the key.
1226 * @param key a String, or null
1227 * @return a float[] value, or null
1230 float[] getFloatArray(@Nullable String key) {
1232 Object o = mMap.get(key);
1238 } catch (ClassCastException e) {
1239 typeWarning(key, o, "float[]", e);
1245 * Returns the value associated with the given key, or null if
1246 * no mapping of the desired type exists for the given key or a null
1247 * value is explicitly associated with the key.
1249 * @param key a String, or null
1250 * @return a double[] value, or null
1253 public double[] getDoubleArray(@Nullable String key) {
1255 Object o = mMap.get(key);
1260 return (double[]) o;
1261 } catch (ClassCastException e) {
1262 typeWarning(key, o, "double[]", e);
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.
1272 * @param key a String, or null
1273 * @return a String[] value, or null
1276 public String[] getStringArray(@Nullable String key) {
1278 Object o = mMap.get(key);
1283 return (String[]) o;
1284 } catch (ClassCastException e) {
1285 typeWarning(key, o, "String[]", e);
1291 * Returns the value associated with the given key, or null if
1292 * no mapping of the desired type exists for the given key or a null
1293 * value is explicitly associated with the key.
1295 * @param key a String, or null
1296 * @return a CharSequence[] value, or null
1299 CharSequence[] getCharSequenceArray(@Nullable String key) {
1301 Object o = mMap.get(key);
1306 return (CharSequence[]) o;
1307 } catch (ClassCastException e) {
1308 typeWarning(key, o, "CharSequence[]", e);
1314 * Writes the Bundle contents to a Parcel, typically in order for
1315 * it to be passed through an IBinder connection.
1316 * @param parcel The parcel to copy this bundle to.
1318 void writeToParcelInner(Parcel parcel, int flags) {
1319 // Keep implementation in sync with writeToParcel() in
1320 // frameworks/native/libs/binder/PersistableBundle.cpp.
1321 if (mParcelledData != null) {
1322 if (mParcelledData == EMPTY_PARCEL) {
1325 int length = mParcelledData.dataSize();
1326 parcel.writeInt(length);
1327 parcel.writeInt(BUNDLE_MAGIC);
1328 parcel.appendFrom(mParcelledData, 0, length);
1331 // Special case for empty bundles.
1332 if (mMap == null || mMap.size() <= 0) {
1336 int lengthPos = parcel.dataPosition();
1337 parcel.writeInt(-1); // dummy, will hold length
1338 parcel.writeInt(BUNDLE_MAGIC);
1340 int startPos = parcel.dataPosition();
1341 parcel.writeArrayMapInternal(mMap);
1342 int endPos = parcel.dataPosition();
1345 parcel.setDataPosition(lengthPos);
1346 int length = endPos - startPos;
1347 parcel.writeInt(length);
1348 parcel.setDataPosition(endPos);
1353 * Reads the Parcel contents into this Bundle, typically in order for
1354 * it to be passed through an IBinder connection.
1355 * @param parcel The parcel to overwrite this bundle from.
1357 void readFromParcelInner(Parcel parcel) {
1358 // Keep implementation in sync with readFromParcel() in
1359 // frameworks/native/libs/binder/PersistableBundle.cpp.
1360 int length = parcel.readInt();
1361 readFromParcelInner(parcel, length);
1364 private void readFromParcelInner(Parcel parcel, int length) {
1366 throw new RuntimeException("Bad length in parcel: " + length);
1368 } else if (length == 0) {
1369 // Empty Bundle or end of data.
1370 mParcelledData = EMPTY_PARCEL;
1374 int magic = parcel.readInt();
1375 if (magic != BUNDLE_MAGIC) {
1376 //noinspection ThrowableInstanceNeverThrown
1377 throw new IllegalStateException("Bad magic number for Bundle: 0x"
1378 + Integer.toHexString(magic));
1381 // Advance within this Parcel
1382 int offset = parcel.dataPosition();
1383 parcel.setDataPosition(MathUtils.addOrThrow(offset, length));
1385 Parcel p = Parcel.obtain();
1386 p.setDataPosition(0);
1387 p.appendFrom(parcel, offset, length);
1388 if (DEBUG) Log.d(TAG, "Retrieving " + Integer.toHexString(System.identityHashCode(this))
1389 + ": " + length + " bundle bytes starting at " + offset);
1390 p.setDataPosition(0);