Bundle详解
Bundle作为intent传递过程中的信息载体,可以通过键值对的方式传递不同的数据
首先初始化的时候有个静态代码块,
用来构建一个EMPTY的bundle
一些重要变量:
Map<String, Object> mMap = null;
Parcel mParcelledData = null;//存放数据的包
//以下三个变量用于Bundle中的深度复制
private boolean mHasFds = false;
private boolean mFdsKnown = true;
private boolean mAllowFds = true;
private ClassLoader mClassLoader;//用于解包的类加载器
再看下bundle的构造方法
1、Bundle() new出来一个HashMap和默认的本类的classLoader
2、Bundle(ClassLoader loader) classLoader使用传入的loader
3、Bundle(int capacity) 设置new出来的HashMap的大小
4、Bundle(Bundle b) copy一个bundle中的数据,深度复制
两个包内访问的:
Bundle(Parcel parcelledData) {//在第一次连接的时候执行解包操作通过classloader
readFromParcel(parcelledData);
}
Bundle(Parcel parcelledData, int length) {
readFromParcelInner(parcelledData, length);
}
如何put或get数据的呢,看一眼:
都有一个unparcel()操作执行解包,看下unparcel是如何实现的
synchronized void unparcel() {//首先是个同步方法,保证多线程时的数据访问
if (mParcelledData == null) {
return;
}
int N = mParcelledData.readInt(); //通过parel可以看出这个方法通过调用native方法返回当前data的dataposition
if (N < 0) {
return;
}
if (mMap == null) {
mMap = new HashMap<String, Object>();
}
mParcelledData.readMapInternal(mMap, N, mClassLoader); //读取数据并存放到mMap中
mParcelledData.recycle(); //回收解包完的数据
mParcelledData = null;
}
这样像在get的时候就return mMap.get(KEY)就可以了
需要注意的是,在get的时候由于返回的都是object对象,所以会检测是否有类型转换异常
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;
}
typeWarning方法中打印错误日志信息 // Log a message if the value was non-null but not of the expected type
Intent通过putExtra传递的数据实际上也是通过Bundle传递的,只不过传递的时候 没有显式的在外面new出一个Bundle对象,而是在putExtra里new出的Bundle对象,get的也是Bundle对象


浙公网安备 33010602011771号