Bundle的使用与解析

Bundle

应用场景举例

Activity:onCreat()、onSaveInstanceState()
Fragment: setArguments()
Message:setData()

源码

//位于android.os包中,final类
public final class Bundle extends BaseBundle implements Cloneable, Parcelable
//实现了Cloneable, Parcelable接口,因此需要重写的方法
public Object clone()
public int describeContents()
public void writeToParcel(Parcel parcel, int flags)
public void readFromParcel(Parcel parcel)
public static final Parcelable.Creator<Bundle> CREATOR = new Parcelable.Creator<Bundle>()

构造方法

Bundle()
Bundle(ClassLoader loader)
Bundle(int capacity)
Bundle(Bundle b)
Bundle(PersistableBundle b)

获取只包含一个键值对的Bundle对象

public static Bundle forPair(String key, String value) {
    Bundle b = new Bundle(1);
    b.putString(key, value);
    return b;
}

put与get方法

​ put()与get()中的key值均为String类型,put()的value值类型为传入的数据类型

相关保存方法 相关读取方法
putBoolean() getBoolean()
putByte() getByte()
putChar() getChar()
putShort() getShort()
putFloat() getFloat()
putCharSequence() getCharSequence()
putParcelable() getParcelable()
putSize() getSize()
putSizeF() getSizeF()
putParcelableArray() getParcelableArray()
putParcelableArrayList() getParcelableArrayList()
putSparseParcelableArray() getSparseParcelableArray()
putIntegerArrayList() getIntegerArrayList()
putStringArrayList() getStringArrayList()
putCharSequenceArrayList() getCharSequenceArrayList()
putSerializable() getSerializable()
putBooleanArray() getBooleanArray()
putByteArray() getByteArray()
putShortArray() getShortArray()
putCharArray() getCharArray()
putFloatArray() getFloatArray()
putCharSequenceArray() getCharSequenceArray()
putBundle() getBundle()
putBinder() getBinder()

清除Bundle数据

清除Bundle中所有数据:clear()

Bundle存取数据具体实现

​ 内部维护了一个ArrayMap,具体定义是在其父类BaseBundle中

void putBoolean(String key, boolean value) {
    unparcel();
    //mMap即为ArrayMap
    mMap.put(key, value);
}
boolean getBoolean(String key) {
    unparcel();
    if (DEBUG) Log.d(TAG, "Getting boolean in "+ Integer.toHexString(System.identityHashCode(this)));
    return getBoolean(key, false);
}
//getBoolean()
boolean getBoolean(String key, boolean defaultValue) {
    unparcel();
    //通过key从ArrayMap里读出保存的数据
    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;
    }
}

ParcelledData解析

​ 三种取值情况:
mParcelledData = EMPTY_PARCEL
mParcelledData = Parcel.obtain()
mParcelledData = null

//定义,mParcelledData = null
Parcel mParcelledData = null;
//创建Bundle
BaseBundle(BaseBundle b) {
    if (b.mParcelledData != null) {
        if (b.mParcelledData == EMPTY_PARCEL) {
            //EMPTY_PARCEL
            mParcelledData = EMPTY_PARCEL;
        } else {
            //Parcel.obtain()
            mParcelledData = Parcel.obtain();
            mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize());
            mParcelledData.setDataPosition(0);
        }
    } else {
        mParcelledData = null;
    }

    if (b.mMap != null) {
        mMap = new ArrayMap<String, Object>(b.mMap);
    } else {
        mMap = null;
    }

    mClassLoader = b.mClassLoader;
}

unparcel()方法解析


/* package */ synchronized void unparcel() {
    if (mParcelledData == null) {
        //如果mParcelledData为null,直接返回
        if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
                + ": no parcelled data");
        return;
    }
	//如果mParcelledData为EMPTY_PARCEL,创建一个容量为1的ArrayMap对象
    if (mParcelledData == EMPTY_PARCEL) {
        if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
                + ": empty");
        if (mMap == null) {
            mMap = new ArrayMap<String, Object>(1);
        } else {
            mMap.erase();
        }
        //mParcelledData置为null
        mParcelledData = null;
        return;
    }
	//如果mParcelledData为Parcel.obtain(),创建一个ArrayMap,再将数据存储到ArrayMap中
    int N = mParcelledData.readInt();
    if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
            + ": reading " + N + " maps");
    if (N < 0) {
        return;
    }
    if (mMap == null) {
        mMap = new ArrayMap<String, Object>(N);
    } else {
        mMap.erase();
        mMap.ensureCapacity(N);
    }
    mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
    //mParcelledData回收并置为null
    mParcelledData.recycle();
    mParcelledData = null;
    if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + " final map: " + mMap);
}

你可能感兴趣的:(Android,Android基础)