/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Set;

A mapping from String keys to values of various types. In most cases, you should work directly with either the Bundle or PersistableBundle subclass.
/** * A mapping from String keys to values of various types. In most cases, you * should work directly with either the {@link Bundle} or * {@link PersistableBundle} subclass. */
public class BaseBundle { private static final String TAG = "Bundle"; static final boolean DEBUG = false; // Keep them in sync with frameworks/native/libs/binder/PersistableBundle.cpp. private static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L' private static final int BUNDLE_MAGIC_NATIVE = 0x4C444E44; // 'B' 'N' 'D' 'N'
Flag indicating that this Bundle is okay to "defuse." That is, it's okay for system processes to ignore any BadParcelableException encountered when unparceling it, leaving an empty bundle in its place.

This should only be set when the Bundle reaches its final destination, otherwise a system process may clobber contents that were destined for an app that could have unparceled them.

/** * Flag indicating that this Bundle is okay to "defuse." That is, it's okay * for system processes to ignore any {@link BadParcelableException} * encountered when unparceling it, leaving an empty bundle in its place. * <p> * This should <em>only</em> be set when the Bundle reaches its final * destination, otherwise a system process may clobber contents that were * destined for an app that could have unparceled them. */
static final int FLAG_DEFUSABLE = 1 << 0; private static final boolean LOG_DEFUSABLE = false; private static volatile boolean sShouldDefuse = false;
Set global variable indicating that any Bundles parsed in this process should be "defused." That is, any BadParcelableException encountered will be suppressed and logged, leaving an empty Bundle instead of crashing.
@hide
/** * Set global variable indicating that any Bundles parsed in this process * should be "defused." That is, any {@link BadParcelableException} * encountered will be suppressed and logged, leaving an empty Bundle * instead of crashing. * * @hide */
public static void setShouldDefuse(boolean shouldDefuse) { sShouldDefuse = shouldDefuse; } // A parcel cannot be obtained during compile-time initialization. Put the // empty parcel into an inner class that can be initialized separately. This // allows to initialize BaseBundle, and classes depending on it.
{@hide}
/** {@hide} */
static final class NoImagePreloadHolder { public static final Parcel EMPTY_PARCEL = Parcel.obtain(); } // Invariant - exactly one of mMap / mParcelledData will be null // (except inside a call to unparcel) ArrayMap<String, Object> mMap = null; /* * If mParcelledData is non-null, then mMap will be null and the * data are stored as a Parcel containing a Bundle. When the data * are unparcelled, mParcelledData willbe set to null. */ Parcel mParcelledData = null;
Whether mParcelledData was generated by native coed or not.
/** * Whether {@link #mParcelledData} was generated by native coed or not. */
private boolean mParcelledByNative;
The ClassLoader used when unparcelling data from mParcelledData.
/** * The ClassLoader used when unparcelling data from mParcelledData. */
private ClassLoader mClassLoader;
{@hide}
/** {@hide} */
@VisibleForTesting public int mFlags;
Constructs a new, empty Bundle that uses a specific ClassLoader for instantiating Parcelable and Serializable objects.
Params:
  • loader – An explicit ClassLoader to use when instantiating objects inside of the Bundle.
  • capacity – Initial size of the ArrayMap.
/** * Constructs a new, empty Bundle that uses a specific ClassLoader for * instantiating Parcelable and Serializable objects. * * @param loader An explicit ClassLoader to use when instantiating objects * inside of the Bundle. * @param capacity Initial size of the ArrayMap. */
BaseBundle(@Nullable ClassLoader loader, int capacity) { mMap = capacity > 0 ? new ArrayMap<String, Object>(capacity) : new ArrayMap<String, Object>(); mClassLoader = loader == null ? getClass().getClassLoader() : loader; }
Constructs a new, empty Bundle.
/** * Constructs a new, empty Bundle. */
BaseBundle() { this((ClassLoader) null, 0); }
Constructs a Bundle whose data is stored as a Parcel. The data will be unparcelled on first contact, using the assigned ClassLoader.
Params:
  • parcelledData – a Parcel containing a Bundle
/** * Constructs a Bundle whose data is stored as a Parcel. The data * will be unparcelled on first contact, using the assigned ClassLoader. * * @param parcelledData a Parcel containing a Bundle */
BaseBundle(Parcel parcelledData) { readFromParcelInner(parcelledData); } BaseBundle(Parcel parcelledData, int length) { readFromParcelInner(parcelledData, length); }
Constructs a new, empty Bundle that uses a specific ClassLoader for instantiating Parcelable and Serializable objects.
Params:
  • loader – An explicit ClassLoader to use when instantiating objects inside of the Bundle.
/** * Constructs a new, empty Bundle that uses a specific ClassLoader for * instantiating Parcelable and Serializable objects. * * @param loader An explicit ClassLoader to use when instantiating objects * inside of the Bundle. */
BaseBundle(ClassLoader loader) { this(loader, 0); }
Constructs a new, empty Bundle sized to hold the given number of elements. The Bundle will grow as needed.
Params:
  • capacity – the initial capacity of the Bundle
/** * Constructs a new, empty Bundle sized to hold the given number of * elements. The Bundle will grow as needed. * * @param capacity the initial capacity of the Bundle */
BaseBundle(int capacity) { this((ClassLoader) null, capacity); }
Constructs a Bundle containing a copy of the mappings from the given Bundle.
Params:
  • b – a Bundle to be copied.
/** * Constructs a Bundle containing a copy of the mappings from the given * Bundle. * * @param b a Bundle to be copied. */
BaseBundle(BaseBundle b) { copyInternal(b, false); }
Special constructor that does not initialize the bundle.
/** * Special constructor that does not initialize the bundle. */
BaseBundle(boolean doInit) { }
TODO: optimize this later (getting just the value part of a Bundle with a single pair) once Bundle.forPair() above is implemented with a special single-value Map implementation/serialization. Note: value in single-pair Bundle may be null.
@hide
/** * TODO: optimize this later (getting just the value part of a Bundle * with a single pair) once Bundle.forPair() above is implemented * with a special single-value Map implementation/serialization. * * Note: value in single-pair Bundle may be null. * * @hide */
public String getPairValue() { unparcel(); int size = mMap.size(); if (size > 1) { Log.w(TAG, "getPairValue() used on Bundle with multiple pairs."); } if (size == 0) { return null; } Object o = mMap.valueAt(0); try { return (String) o; } catch (ClassCastException e) { typeWarning("getPairValue()", o, "String", e); return null; } }
Changes the ClassLoader this Bundle uses when instantiating objects.
Params:
  • loader – An explicit ClassLoader to use when instantiating objects inside of the Bundle.
/** * Changes the ClassLoader this Bundle uses when instantiating objects. * * @param loader An explicit ClassLoader to use when instantiating objects * inside of the Bundle. */
void setClassLoader(ClassLoader loader) { mClassLoader = loader; }
Return the ClassLoader currently associated with this Bundle.
/** * Return the ClassLoader currently associated with this Bundle. */
ClassLoader getClassLoader() { return mClassLoader; }
If the underlying data are stored as a Parcel, unparcel them using the currently assigned class loader.
/** * If the underlying data are stored as a Parcel, unparcel them * using the currently assigned class loader. */
/* package */ void unparcel() { synchronized (this) { final Parcel source = mParcelledData; if (source != null) { initializeFromParcelLocked(source, /*recycleParcel=*/ true, mParcelledByNative); } else { if (DEBUG) { Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + ": no parcelled data"); } } } } private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel, boolean parcelledByNative) { if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) { Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may " + "clobber all data inside!", new Throwable()); } if (isEmptyParcel(parcelledData)) { if (DEBUG) { Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + ": empty"); } if (mMap == null) { mMap = new ArrayMap<>(1); } else { mMap.erase(); } mParcelledData = null; mParcelledByNative = false; return; } final int count = parcelledData.readInt(); if (DEBUG) { Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + ": reading " + count + " maps"); } if (count < 0) { return; } ArrayMap<String, Object> map = mMap; if (map == null) { map = new ArrayMap<>(count); } else { map.erase(); map.ensureCapacity(count); } try { if (parcelledByNative) { // If it was parcelled by native code, then the array map keys aren't sorted // by their hash codes, so use the safe (slow) one. parcelledData.readArrayMapSafelyInternal(map, count, mClassLoader); } else { // If parcelled by Java, we know the contents are sorted properly, // so we can use ArrayMap.append(). parcelledData.readArrayMapInternal(map, count, mClassLoader); } } catch (BadParcelableException e) { if (sShouldDefuse) { Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); map.erase(); } else { throw e; } } finally { mMap = map; if (recycleParcel) { recycleParcel(parcelledData); } mParcelledData = null; mParcelledByNative = false; } if (DEBUG) { Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + " final map: " + mMap); } }
@hide
/** * @hide */
public boolean isParcelled() { return mParcelledData != null; }
@hide
/** * @hide */
public boolean isEmptyParcel() { return isEmptyParcel(mParcelledData); }
@hide
/** * @hide */
private static boolean isEmptyParcel(Parcel p) { return p == NoImagePreloadHolder.EMPTY_PARCEL; } private static void recycleParcel(Parcel p) { if (p != null && !isEmptyParcel(p)) { p.recycle(); } }
@hide
/** @hide */
ArrayMap<String, Object> getMap() { unparcel(); return mMap; }
Returns the number of mappings contained in this Bundle.
Returns:the number of mappings as an int.
/** * Returns the number of mappings contained in this Bundle. * * @return the number of mappings as an int. */
public int size() { unparcel(); return mMap.size(); }
Returns true if the mapping of this Bundle is empty, false otherwise.
/** * Returns true if the mapping of this Bundle is empty, false otherwise. */
public boolean isEmpty() { unparcel(); return mMap.isEmpty(); }
@hidethis should probably be the implementation of isEmpty(). To do that we need to ensure we always use the special empty parcel form when the bundle is empty. (This may already be the case, but to be safe we'll do this later when we aren't trying to stabilize.)
/** * @hide this should probably be the implementation of isEmpty(). To do that we * need to ensure we always use the special empty parcel form when the bundle is * empty. (This may already be the case, but to be safe we'll do this later when * we aren't trying to stabilize.) */
public boolean maybeIsEmpty() { if (isParcelled()) { return isEmptyParcel(); } else { return isEmpty(); } }
Does a loose equality check between two given BaseBundle objects. Returns true if both are null, or if both are equal as per kindofEquals(BaseBundle)
Params:
See Also:
Returns:true if both are the same, false otherwise
@hide
/** * Does a loose equality check between two given {@link BaseBundle} objects. * Returns {@code true} if both are {@code null}, or if both are equal as per * {@link #kindofEquals(BaseBundle)} * * @param a A {@link BaseBundle} object * @param b Another {@link BaseBundle} to compare with a * @return {@code true} if both are the same, {@code false} otherwise * * @see #kindofEquals(BaseBundle) * * @hide */
public static boolean kindofEquals(BaseBundle a, BaseBundle b) { return (a == b) || (a != null && a.kindofEquals(b)); }
@hideThis kind-of does an equality comparison. Kind-of.
/** * @hide This kind-of does an equality comparison. Kind-of. */
public boolean kindofEquals(BaseBundle other) { if (other == null) { return false; } if (isParcelled() != other.isParcelled()) { // Big kind-of here! return false; } else if (isParcelled()) { return mParcelledData.compareData(other.mParcelledData) == 0; } else { return mMap.equals(other.mMap); } }
Removes all elements from the mapping of this Bundle.
/** * Removes all elements from the mapping of this Bundle. */
public void clear() { unparcel(); mMap.clear(); } void copyInternal(BaseBundle from, boolean deep) { synchronized (from) { if (from.mParcelledData != null) { if (from.isEmptyParcel()) { mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL; mParcelledByNative = false; } else { mParcelledData = Parcel.obtain(); mParcelledData.appendFrom(from.mParcelledData, 0, from.mParcelledData.dataSize()); mParcelledData.setDataPosition(0); mParcelledByNative = from.mParcelledByNative; } } else { mParcelledData = null; mParcelledByNative = false; } if (from.mMap != null) { if (!deep) { mMap = new ArrayMap<>(from.mMap); } else { final ArrayMap<String, Object> fromMap = from.mMap; final int N = fromMap.size(); mMap = new ArrayMap<>(N); for (int i = 0; i < N; i++) { mMap.append(fromMap.keyAt(i), deepCopyValue(fromMap.valueAt(i))); } } } else { mMap = null; } mClassLoader = from.mClassLoader; } } Object deepCopyValue(Object value) { if (value == null) { return null; } if (value instanceof Bundle) { return ((Bundle)value).deepCopy(); } else if (value instanceof PersistableBundle) { return ((PersistableBundle)value).deepCopy(); } else if (value instanceof ArrayList) { return deepcopyArrayList((ArrayList) value); } else if (value.getClass().isArray()) { if (value instanceof int[]) { return ((int[])value).clone(); } else if (value instanceof long[]) { return ((long[])value).clone(); } else if (value instanceof float[]) { return ((float[])value).clone(); } else if (value instanceof double[]) { return ((double[])value).clone(); } else if (value instanceof Object[]) { return ((Object[])value).clone(); } else if (value instanceof byte[]) { return ((byte[])value).clone(); } else if (value instanceof short[]) { return ((short[])value).clone(); } else if (value instanceof char[]) { return ((char[]) value).clone(); } } return value; } ArrayList deepcopyArrayList(ArrayList from) { final int N = from.size(); ArrayList out = new ArrayList(N); for (int i=0; i<N; i++) { out.add(deepCopyValue(from.get(i))); } return out; }
Returns true if the given key is contained in the mapping of this Bundle.
Params:
  • key – a String key
Returns:true if the key is part of the mapping, false otherwise
/** * Returns true if the given key is contained in the mapping * of this Bundle. * * @param key a String key * @return true if the key is part of the mapping, false otherwise */
public boolean containsKey(String key) { unparcel(); return mMap.containsKey(key); }
Returns the entry with the given key as an object.
Params:
  • key – a String key
Returns:an Object, or null
/** * Returns the entry with the given key as an object. * * @param key a String key * @return an Object, or null */
@Nullable public Object get(String key) { unparcel(); return mMap.get(key); }
Removes any entry with the given key from the mapping of this Bundle.
Params:
  • key – a String key
/** * Removes any entry with the given key from the mapping of this Bundle. * * @param key a String key */
public void remove(String key) { unparcel(); mMap.remove(key); }
Inserts all mappings from the given PersistableBundle into this BaseBundle.
Params:
  • bundle – a PersistableBundle
/** * Inserts all mappings from the given PersistableBundle into this BaseBundle. * * @param bundle a PersistableBundle */
public void putAll(PersistableBundle bundle) { unparcel(); bundle.unparcel(); mMap.putAll(bundle.mMap); }
Inserts all mappings from the given Map into this BaseBundle.
Params:
  • map – a Map
/** * Inserts all mappings from the given Map into this BaseBundle. * * @param map a Map */
void putAll(ArrayMap map) { unparcel(); mMap.putAll(map); }
Returns a Set containing the Strings used as keys in this Bundle.
Returns:a Set of String keys
/** * Returns a Set containing the Strings used as keys in this Bundle. * * @return a Set of String keys */
public Set<String> keySet() { unparcel(); return mMap.keySet(); }
Inserts a Boolean value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a boolean
/** * Inserts a Boolean value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a boolean */
public void putBoolean(@Nullable String key, boolean value) { unparcel(); mMap.put(key, value); }
Inserts a byte value into the mapping of this Bundle, replacing any existing value for the given key.
Params:
  • key – a String, or null
  • value – a byte
/** * Inserts a byte value into the mapping of this Bundle, replacing * any existing value for the given key. * * @param key a String, or null * @param value a byte */
void putByte(@Nullable String key, byte value) { unparcel(); mMap.put(key, value); }
Inserts a char value into the mapping of this Bundle, replacing any existing value for the given key.
Params:
  • key – a String, or null
  • value – a char
/** * Inserts a char value into the mapping of this Bundle, replacing * any existing value for the given key. * * @param key a String, or null * @param value a char */
void putChar(@Nullable String key, char value) { unparcel(); mMap.put(key, value); }
Inserts a short value into the mapping of this Bundle, replacing any existing value for the given key.
Params:
  • key – a String, or null
  • value – a short
/** * Inserts a short value into the mapping of this Bundle, replacing * any existing value for the given key. * * @param key a String, or null * @param value a short */
void putShort(@Nullable String key, short value) { unparcel(); mMap.put(key, value); }
Inserts an int value into the mapping of this Bundle, replacing any existing value for the given key.
Params:
  • key – a String, or null
  • value – an int
/** * Inserts an int value into the mapping of this Bundle, replacing * any existing value for the given key. * * @param key a String, or null * @param value an int */
public void putInt(@Nullable String key, int value) { unparcel(); mMap.put(key, value); }
Inserts a long value into the mapping of this Bundle, replacing any existing value for the given key.
Params:
  • key – a String, or null
  • value – a long
/** * Inserts a long value into the mapping of this Bundle, replacing * any existing value for the given key. * * @param key a String, or null * @param value a long */
public void putLong(@Nullable String key, long value) { unparcel(); mMap.put(key, value); }
Inserts a float value into the mapping of this Bundle, replacing any existing value for the given key.
Params:
  • key – a String, or null
  • value – a float
/** * Inserts a float value into the mapping of this Bundle, replacing * any existing value for the given key. * * @param key a String, or null * @param value a float */
void putFloat(@Nullable String key, float value) { unparcel(); mMap.put(key, value); }
Inserts a double value into the mapping of this Bundle, replacing any existing value for the given key.
Params:
  • key – a String, or null
  • value – a double
/** * Inserts a double value into the mapping of this Bundle, replacing * any existing value for the given key. * * @param key a String, or null * @param value a double */
public void putDouble(@Nullable String key, double value) { unparcel(); mMap.put(key, value); }
Inserts a String value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a String, or null
/** * Inserts a String value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a String, or null */
public void putString(@Nullable String key, @Nullable String value) { unparcel(); mMap.put(key, value); }
Inserts a CharSequence value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a CharSequence, or null
/** * Inserts a CharSequence value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a CharSequence, or null */
void putCharSequence(@Nullable String key, @Nullable CharSequence value) { unparcel(); mMap.put(key, value); }
Inserts an ArrayList value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – an ArrayList object, or null
/** * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value an ArrayList<Integer> object, or null */
void putIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) { unparcel(); mMap.put(key, value); }
Inserts an ArrayList value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – an ArrayList object, or null
/** * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value an ArrayList<String> object, or null */
void putStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) { unparcel(); mMap.put(key, value); }
Inserts an ArrayList value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – an ArrayList object, or null
/** * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value an ArrayList<CharSequence> object, or null */
void putCharSequenceArrayList(@Nullable String key, @Nullable ArrayList<CharSequence> value) { unparcel(); mMap.put(key, value); }
Inserts a Serializable value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a Serializable object, or null
/** * Inserts a Serializable value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a Serializable object, or null */
void putSerializable(@Nullable String key, @Nullable Serializable value) { unparcel(); mMap.put(key, value); }
Inserts a boolean array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a boolean array object, or null
/** * Inserts a boolean array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a boolean array object, or null */
public void putBooleanArray(@Nullable String key, @Nullable boolean[] value) { unparcel(); mMap.put(key, value); }
Inserts a byte array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a byte array object, or null
/** * Inserts a byte array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a byte array object, or null */
void putByteArray(@Nullable String key, @Nullable byte[] value) { unparcel(); mMap.put(key, value); }
Inserts a short array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a short array object, or null
/** * Inserts a short array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a short array object, or null */
void putShortArray(@Nullable String key, @Nullable short[] value) { unparcel(); mMap.put(key, value); }
Inserts a char array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a char array object, or null
/** * Inserts a char array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a char array object, or null */
void putCharArray(@Nullable String key, @Nullable char[] value) { unparcel(); mMap.put(key, value); }
Inserts an int array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – an int array object, or null
/** * Inserts an int array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value an int array object, or null */
public void putIntArray(@Nullable String key, @Nullable int[] value) { unparcel(); mMap.put(key, value); }
Inserts a long array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a long array object, or null
/** * Inserts a long array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a long array object, or null */
public void putLongArray(@Nullable String key, @Nullable long[] value) { unparcel(); mMap.put(key, value); }
Inserts a float array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a float array object, or null
/** * Inserts a float array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a float array object, or null */
void putFloatArray(@Nullable String key, @Nullable float[] value) { unparcel(); mMap.put(key, value); }
Inserts a double array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a double array object, or null
/** * Inserts a double array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a double array object, or null */
public void putDoubleArray(@Nullable String key, @Nullable double[] value) { unparcel(); mMap.put(key, value); }
Inserts a String array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a String array object, or null
/** * Inserts a String array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a String array object, or null */
public void putStringArray(@Nullable String key, @Nullable String[] value) { unparcel(); mMap.put(key, value); }
Inserts a CharSequence array value into the mapping of this Bundle, replacing any existing value for the given key. Either key or value may be null.
Params:
  • key – a String, or null
  • value – a CharSequence array object, or null
/** * Inserts a CharSequence array value into the mapping of this Bundle, replacing * any existing value for the given key. Either key or value may be null. * * @param key a String, or null * @param value a CharSequence array object, or null */
void putCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) { unparcel(); mMap.put(key, value); }
Returns the value associated with the given key, or false if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:a boolean value
/** * Returns the value associated with the given key, or false if * no mapping of the desired type exists for the given key. * * @param key a String * @return a boolean value */
public boolean getBoolean(String key) { unparcel(); if (DEBUG) Log.d(TAG, "Getting boolean in " + Integer.toHexString(System.identityHashCode(this))); return getBoolean(key, false); } // Log a message if the value was non-null but not of the expected type void typeWarning(String key, Object value, String className, Object defaultValue, ClassCastException e) { StringBuilder sb = new StringBuilder(); sb.append("Key "); sb.append(key); sb.append(" expected "); sb.append(className); sb.append(" but value was a "); sb.append(value.getClass().getName()); sb.append(". The default value "); sb.append(defaultValue); sb.append(" was returned."); Log.w(TAG, sb.toString()); Log.w(TAG, "Attempt to cast generated internal exception:", e); } void typeWarning(String key, Object value, String className, ClassCastException e) { typeWarning(key, value, className, "<null>", e); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:a boolean value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return a boolean value */
public boolean getBoolean(String key, boolean defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Boolean) o; } catch (ClassCastException e) { typeWarning(key, o, "Boolean", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or (byte) 0 if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:a byte value
/** * Returns the value associated with the given key, or (byte) 0 if * no mapping of the desired type exists for the given key. * * @param key a String * @return a byte value */
byte getByte(String key) { unparcel(); return getByte(key, (byte) 0); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:a byte value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return a byte value */
Byte getByte(String key, byte defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Byte) o; } catch (ClassCastException e) { typeWarning(key, o, "Byte", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or (char) 0 if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:a char value
/** * Returns the value associated with the given key, or (char) 0 if * no mapping of the desired type exists for the given key. * * @param key a String * @return a char value */
char getChar(String key) { unparcel(); return getChar(key, (char) 0); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:a char value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return a char value */
char getChar(String key, char defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Character) o; } catch (ClassCastException e) { typeWarning(key, o, "Character", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or (short) 0 if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:a short value
/** * Returns the value associated with the given key, or (short) 0 if * no mapping of the desired type exists for the given key. * * @param key a String * @return a short value */
short getShort(String key) { unparcel(); return getShort(key, (short) 0); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:a short value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return a short value */
short getShort(String key, short defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Short) o; } catch (ClassCastException e) { typeWarning(key, o, "Short", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or 0 if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:an int value
/** * Returns the value associated with the given key, or 0 if * no mapping of the desired type exists for the given key. * * @param key a String * @return an int value */
public int getInt(String key) { unparcel(); return getInt(key, 0); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:an int value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return an int value */
public int getInt(String key, int defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Integer) o; } catch (ClassCastException e) { typeWarning(key, o, "Integer", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or 0L if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:a long value
/** * Returns the value associated with the given key, or 0L if * no mapping of the desired type exists for the given key. * * @param key a String * @return a long value */
public long getLong(String key) { unparcel(); return getLong(key, 0L); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:a long value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return a long value */
public long getLong(String key, long defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Long) o; } catch (ClassCastException e) { typeWarning(key, o, "Long", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or 0.0f if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:a float value
/** * Returns the value associated with the given key, or 0.0f if * no mapping of the desired type exists for the given key. * * @param key a String * @return a float value */
float getFloat(String key) { unparcel(); return getFloat(key, 0.0f); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:a float value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return a float value */
float getFloat(String key, float defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Float) o; } catch (ClassCastException e) { typeWarning(key, o, "Float", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or 0.0 if no mapping of the desired type exists for the given key.
Params:
  • key – a String
Returns:a double value
/** * Returns the value associated with the given key, or 0.0 if * no mapping of the desired type exists for the given key. * * @param key a String * @return a double value */
public double getDouble(String key) { unparcel(); return getDouble(key, 0.0); }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key.
Params:
  • key – a String
  • defaultValue – Value to return if key does not exist
Returns:a double value
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. * * @param key a String * @param defaultValue Value to return if key does not exist * @return a double value */
public double getDouble(String key, double defaultValue) { unparcel(); Object o = mMap.get(key); if (o == null) { return defaultValue; } try { return (Double) o; } catch (ClassCastException e) { typeWarning(key, o, "Double", defaultValue, e); return defaultValue; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a String value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a String value, or null */
@Nullable public String getString(@Nullable String key) { unparcel(); final Object o = mMap.get(key); try { return (String) o; } catch (ClassCastException e) { typeWarning(key, o, "String", e); return null; } }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key or if a null value is explicitly associated with the given key.
Params:
  • key – a String, or null
  • defaultValue – Value to return if key does not exist or if a null value is associated with the given key.
Returns:the String value associated with the given key, or defaultValue if no valid String object is currently mapped to that key.
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key or if a null * value is explicitly associated with the given key. * * @param key a String, or null * @param defaultValue Value to return if key does not exist or if a null * value is associated with the given key. * @return the String value associated with the given key, or defaultValue * if no valid String object is currently mapped to that key. */
public String getString(@Nullable String key, String defaultValue) { final String s = getString(key); return (s == null) ? defaultValue : s; }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a CharSequence value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a CharSequence value, or null */
@Nullable CharSequence getCharSequence(@Nullable String key) { unparcel(); final Object o = mMap.get(key); try { return (CharSequence) o; } catch (ClassCastException e) { typeWarning(key, o, "CharSequence", e); return null; } }
Returns the value associated with the given key, or defaultValue if no mapping of the desired type exists for the given key or if a null value is explicitly associated with the given key.
Params:
  • key – a String, or null
  • defaultValue – Value to return if key does not exist or if a null value is associated with the given key.
Returns:the CharSequence value associated with the given key, or defaultValue if no valid CharSequence object is currently mapped to that key.
/** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key or if a null * value is explicitly associated with the given key. * * @param key a String, or null * @param defaultValue Value to return if key does not exist or if a null * value is associated with the given key. * @return the CharSequence value associated with the given key, or defaultValue * if no valid CharSequence object is currently mapped to that key. */
CharSequence getCharSequence(@Nullable String key, CharSequence defaultValue) { final CharSequence cs = getCharSequence(key); return (cs == null) ? defaultValue : cs; }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a Serializable value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a Serializable value, or null */
@Nullable Serializable getSerializable(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (Serializable) o; } catch (ClassCastException e) { typeWarning(key, o, "Serializable", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:an ArrayList value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return an ArrayList<String> value, or null */
@Nullable ArrayList<Integer> getIntegerArrayList(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (ArrayList<Integer>) o; } catch (ClassCastException e) { typeWarning(key, o, "ArrayList<Integer>", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:an ArrayList value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return an ArrayList<String> value, or null */
@Nullable ArrayList<String> getStringArrayList(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (ArrayList<String>) o; } catch (ClassCastException e) { typeWarning(key, o, "ArrayList<String>", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:an ArrayList value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return an ArrayList<CharSequence> value, or null */
@Nullable ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (ArrayList<CharSequence>) o; } catch (ClassCastException e) { typeWarning(key, o, "ArrayList<CharSequence>", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a boolean[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a boolean[] value, or null */
@Nullable public boolean[] getBooleanArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (boolean[]) o; } catch (ClassCastException e) { typeWarning(key, o, "byte[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a byte[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a byte[] value, or null */
@Nullable byte[] getByteArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (byte[]) o; } catch (ClassCastException e) { typeWarning(key, o, "byte[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a short[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a short[] value, or null */
@Nullable short[] getShortArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (short[]) o; } catch (ClassCastException e) { typeWarning(key, o, "short[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a char[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a char[] value, or null */
@Nullable char[] getCharArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (char[]) o; } catch (ClassCastException e) { typeWarning(key, o, "char[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:an int[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return an int[] value, or null */
@Nullable public int[] getIntArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (int[]) o; } catch (ClassCastException e) { typeWarning(key, o, "int[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a long[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a long[] value, or null */
@Nullable public long[] getLongArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (long[]) o; } catch (ClassCastException e) { typeWarning(key, o, "long[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a float[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a float[] value, or null */
@Nullable float[] getFloatArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (float[]) o; } catch (ClassCastException e) { typeWarning(key, o, "float[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a double[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a double[] value, or null */
@Nullable public double[] getDoubleArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (double[]) o; } catch (ClassCastException e) { typeWarning(key, o, "double[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a String[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a String[] value, or null */
@Nullable public String[] getStringArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (String[]) o; } catch (ClassCastException e) { typeWarning(key, o, "String[]", e); return null; } }
Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Params:
  • key – a String, or null
Returns:a CharSequence[] value, or null
/** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a CharSequence[] value, or null */
@Nullable CharSequence[] getCharSequenceArray(@Nullable String key) { unparcel(); Object o = mMap.get(key); if (o == null) { return null; } try { return (CharSequence[]) o; } catch (ClassCastException e) { typeWarning(key, o, "CharSequence[]", e); return null; } }
Writes the Bundle contents to a Parcel, typically in order for it to be passed through an IBinder connection.
Params:
  • parcel – The parcel to copy this bundle to.
/** * Writes the Bundle contents to a Parcel, typically in order for * it to be passed through an IBinder connection. * @param parcel The parcel to copy this bundle to. */
void writeToParcelInner(Parcel parcel, int flags) { // If the parcel has a read-write helper, we can't just copy the blob, so unparcel it first. if (parcel.hasReadWriteHelper()) { unparcel(); } // Keep implementation in sync with writeToParcel() in // frameworks/native/libs/binder/PersistableBundle.cpp. final ArrayMap<String, Object> map; synchronized (this) { // unparcel() can race with this method and cause the parcel to recycle // at the wrong time. So synchronize access the mParcelledData's content. if (mParcelledData != null) { if (mParcelledData == NoImagePreloadHolder.EMPTY_PARCEL) { parcel.writeInt(0); } else { int length = mParcelledData.dataSize(); parcel.writeInt(length); parcel.writeInt(mParcelledByNative ? BUNDLE_MAGIC_NATIVE : BUNDLE_MAGIC); parcel.appendFrom(mParcelledData, 0, length); } return; } map = mMap; } // Special case for empty bundles. if (map == null || map.size() <= 0) { parcel.writeInt(0); return; } int lengthPos = parcel.dataPosition(); parcel.writeInt(-1); // dummy, will hold length parcel.writeInt(BUNDLE_MAGIC); int startPos = parcel.dataPosition(); parcel.writeArrayMapInternal(map); int endPos = parcel.dataPosition(); // Backpatch length parcel.setDataPosition(lengthPos); int length = endPos - startPos; parcel.writeInt(length); parcel.setDataPosition(endPos); }
Reads the Parcel contents into this Bundle, typically in order for it to be passed through an IBinder connection.
Params:
  • parcel – The parcel to overwrite this bundle from.
/** * Reads the Parcel contents into this Bundle, typically in order for * it to be passed through an IBinder connection. * @param parcel The parcel to overwrite this bundle from. */
void readFromParcelInner(Parcel parcel) { // Keep implementation in sync with readFromParcel() in // frameworks/native/libs/binder/PersistableBundle.cpp. int length = parcel.readInt(); readFromParcelInner(parcel, length); } private void readFromParcelInner(Parcel parcel, int length) { if (length < 0) { throw new RuntimeException("Bad length in parcel: " + length); } else if (length == 0) { // Empty Bundle or end of data. mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL; mParcelledByNative = false; return; } final int magic = parcel.readInt(); final boolean isJavaBundle = magic == BUNDLE_MAGIC; final boolean isNativeBundle = magic == BUNDLE_MAGIC_NATIVE; if (!isJavaBundle && !isNativeBundle) { throw new IllegalStateException("Bad magic number for Bundle: 0x" + Integer.toHexString(magic)); } if (parcel.hasReadWriteHelper()) { // If the parcel has a read-write helper, then we can't lazily-unparcel it, so just // unparcel right away. synchronized (this) { initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle); } return; } // Advance within this Parcel int offset = parcel.dataPosition(); parcel.setDataPosition(MathUtils.addOrThrow(offset, length)); Parcel p = Parcel.obtain(); p.setDataPosition(0); p.appendFrom(parcel, offset, length); p.adoptClassCookies(parcel); if (DEBUG) Log.d(TAG, "Retrieving " + Integer.toHexString(System.identityHashCode(this)) + ": " + length + " bundle bytes starting at " + offset); p.setDataPosition(0); mParcelledData = p; mParcelledByNative = isNativeBundle; }
{@hide}
/** {@hide} */
public static void dumpStats(IndentingPrintWriter pw, String key, Object value) { final Parcel tmp = Parcel.obtain(); tmp.writeValue(value); final int size = tmp.dataPosition(); tmp.recycle(); // We only really care about logging large values if (size > 1024) { pw.println(key + " [size=" + size + "]"); if (value instanceof BaseBundle) { dumpStats(pw, (BaseBundle) value); } else if (value instanceof SparseArray) { dumpStats(pw, (SparseArray) value); } } }
{@hide}
/** {@hide} */
public static void dumpStats(IndentingPrintWriter pw, SparseArray array) { pw.increaseIndent(); if (array == null) { pw.println("[null]"); return; } for (int i = 0; i < array.size(); i++) { dumpStats(pw, "0x" + Integer.toHexString(array.keyAt(i)), array.valueAt(i)); } pw.decreaseIndent(); }
{@hide}
/** {@hide} */
public static void dumpStats(IndentingPrintWriter pw, BaseBundle bundle) { pw.increaseIndent(); if (bundle == null) { pw.println("[null]"); return; } final ArrayMap<String, Object> map = bundle.getMap(); for (int i = 0; i < map.size(); i++) { dumpStats(pw, map.keyAt(i), map.valueAt(i)); } pw.decreaseIndent(); } }