我们都知道,在 Android 应用开发中,需要数据和状态的传递,其中还包括在 跨进程 之间的传递 (比如 IPC/Binder)。关于数据传递有多种方式,其中最常见的就是通过 Bundle 。Bundle 中文意思:捆; 一批,顾名思义就很直观了。
实现
Activity 之间可以通过 创建 intent 并传递参数 的方式来传递,
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("media_id", "a1b2c3");
...
startActivity(intent);
在当前 Activity 打包数据,在 目标 Activity 解包数据。
通过查看 Api ,我们可以知道 一些常规数据类型,如:int、string、boolean 等经过简单的设置,都没什么问题。但是我们如果想通过一定机制,传递一些复杂的复合对象呢?
这就需要 Parcelables 了。
传递复杂数据 可以查看相应的文章。
- 通过 Bundle 进行数据,要注意以下问题
- 复杂对象 通过 Parcelables 或者 seriable。
- 对象最大 不能超过 1 mb,否则会出现
TransactionTooLargeException
错误。7.0 (API level 24) 或更高系统上会报出,其他系统会有警告log。 -
savedInstanceState
保存数据状态,系统运行中这些保存的数据会一直存在,所以尽可能小于 50kb,否则会照成资源的浪费。
以上是bundle 如何使用以及需要注意的事项。
Parcel不是通用的序列化机制(Serializable是通用的序列化机制) 所以不能把 Parcel数据存储在磁盘上或通过网络发送出去。
源码分析
通过源码查看,Bundle 继承 BaseBundle 且实现了 Parcelable 接口。BaseBundle 内部 维护一个 ArrayMap<String, Object> mMap 常量来承载我们需要操作的对象。
public final class Bundle extends BaseBundle implements Cloneable, Parcelable
BaseBundle 声明常量 mMap:
ArrayMap<String, Object> mMap = null;
通过
Bundle bundle=new Bundle();
bundle.putXX(Object object);
实际上内部执行的是对 ArrayMap 的操作
void putXXX(@Nullable String key, Object value) {
unparcel();
mMap.put(key, value);
}