Bundle详解

Bundle作为intent传递过程中的信息载体,可以通过键值对的方式传递不同的数据

首先初始化的时候有个静态代码块,

Image

用来构建一个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对象

posted @ 2015-08-24 13:59  Assasin哲  阅读(2660)  评论(0)    收藏  举报