在安卓sdk源码中,Bundle类的说明是这样的
A mapping from String keys to various Parcelable values.
See Also:
PersistableBundle
public final class Bundle extends BaseBundle implements Cloneable, Parcelable
字符串的键到持久化值的映射。
经常被用作Activity跳转时传递数据,也时常被用作Handler传递Message时携带数据。
Activity跳转时传递数据最常见
Bundle bundle = new Bundle();
所有可传递的数据类型如上图。
不过,在开发过程过程中,迭代是不可避免的,随着需求和业务增多,页面之后传递的值也可能会逐渐增多,如果接手别人迭代过的项目,可能页面传递的值多的根本看不懂,也不能轻易删除,牵一发而动全身。也可能会把自己的烂摊子留给其他人,此时,如果能留下一手漂亮的迭代版本,成就感会很强。
所以如何避免随着迭代导致的传递数据困难呢?可以用实体类封装传递的数据。
但是实体类是一个(object)对象,而bundle又不支持传递对象。可能有开发经验的同学知道用序列化的方式传递对象,当然也不失为很好的一种方法。
这里我有一个粗鄙的方法分享一下(实体类如果用java的方式表现,可能代码量会很大,这里我用kotlin做了简化):
data class MyData(
var user: String = "",
var name: String = "",
var age: String = "",
var height: String = "",
var width: String = "",
var weight: Int = 0,
var father: Int = -1,
var mother: Int = 0,
var son: Int = 0,
var daughter: String = "",
var sister: String? = "",
var brother: String? = "",
var friend: String = ""
) {
override fun toString(): String {
return "{user:\"$user\"," +
"name:\"$name\"," +
"age:\"$age\"," +
"name:\"$name\"," +
"height:\"$height\"," +
"width:\"$width\"," +
"weight:\"$weight\"," +
"father:\"$father\"," +
"mother:\"$mother\"," +
"son:\"$son\"," +
"daughter:\"$daughter\"," +
"sister:\"$sister\"," +
"brother:\"$brother\"," +
"friend:\"$friend\"}"
}
}
重写toString方法,把实体类的字段转化成json类型,这样就可以通过putString的方式把这个实体类传递到目标Activity;
在目标Activity中通过Gson工具把json字符串转化成实体类对象就可以完成传递。
val myData = Gson().fromJson("", MyData::class.java)
这种方式传递,可以有效避免因为迭代增加传递量的增大导致的代码阅读难度高,逻辑复杂等问题。
后期增加字段时,只需要给实体类增加一个字段,然后扩充一下toString方法中的json字段就可以完成需求,这种零存整取的方法不仅看着简介,使用起来也很方便。
如果有同学使用过EventBus,也可以完成上述需求。不过我个人不太推崇EventBus。因为如果项目迭代过程中代码量增大,EventBus乱用会导致逻辑非常复杂。尤其是UI和Data交互时,大量的EventBus重写的方法会让逻辑交互产生很多耦合现象。
EventBus比较适合用于小项目,或者模块之间的数据传递,Activity之间的数据传递尽可能使用原生的Bundle。
Handler中传递Message的用法和Acvitiy基本一样。Message的优势在与可以直接传递Object
val camera = Camera()
val message = Message()
message.what = 0x00
message.obj = camera
handler?.sendMessage(message)
可能有人尝试过用Bundle携带Bitmap这样的对象,遇到过报错。
对于这种占用空间很大的对象,不建议或者说禁用Bundle传递,最好的做法是把这样的对象保存到本地,然后传递url的方式,在目标Activity中重写加载读取对象。