bundle.putSerializable 或者 bundle.putParcelable 传进去的对象一定要implements Parcelable 或者 Serializable 这两个接口。
Serializable 这个接口没有具体的方法,这个关键字主要是标识这个类在jdk编译的时候会被序列化处理。在序列化处理的过程中,会大量生成中间临时变量。可能引起GC操作。
对于Parcelable 这个接口:
为什么有Serializable,有它就有反序列化,有一个问题:我这边使用Java Serializable生成二进制文件,通过网络传输到其他设备上,此设备是Linux,那么如何使用C语言将其方序列化,读数据文件?能做到吗?
Parcel的存在主要是jvm 进程之间的通信,进程是占有系统资源的最小程序,其包含一个或者多个线程。进程之间的通信,其可以上升到应用之间的通信,所以基于Parcel,android系统有Binder IPC进程通信机制和AIDL开发。什么是通信?
通信:1.共享数据或者传递数据 2.通知对方调用自身的变量和代码执行指令
为什么非要让别人调用自己的资源执行自己的指令,比如:子线程要通知弹出窗口,那么自己不能做到,自己没有window服务,只能让UI线程去做。
为什么非要传递数据,直接让数据的可见性(对象的可见性)让两个线程或者进程可见不就可以了吗?可见性和生命周期直接相关的,可见性越大,那么生命周期越长。占内存!对于我们传统的传递对象,就是将对象的可见性扩大,如下图:
bundle在activity之间或者fragment之间使用Parcelable,Serializable传递对象是线程内部的数据交互,不属于线程或者进程间的通信。
但是有一个问题:jvm线程内部传递对象为何不能直接传,还需要序列化呢?但是handler传递消息是可以直接传递对象的。
Parcelable的使用:
publicclassDataBean
implements
Parcelable{
// 写数据进行保存
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.Account);
dest.writeString(this.name);
dest.writeString(this.password);
dest.writeInt(this.kind);
dest.writeString(this.desc);
}
// 读数据进行恢复
protected DataBean(Parcel in) {
this.id = in.readInt();
this.kind = in.readInt();
this.password = in.readString();
this.name = in.readString();
this.Account = in.readString();
this.desc = in.readString();
}
intent.putExtra("data",data);
DataBean data = getIntent().getParcelableExtra("data");
注意的问题:顺序写进去的数据,读出来的时候也要按照这个顺序,否则数据就会错位。
为什么aidl或者IPC通信基于parcel:
从parcel的使用可以看出,parcel就是连续保存数据的单纯地址结构,它和jvm中的对象的结构有很大的不同。对于android系统,其应用都是跑在jvm上的,那么各个进程也是跑在j各个独立的vm上的,进程之间的通信是跨jvm,那么必然数据先是从一个jvm到普通Linux(android系统基于Linux内核)管理的内存,然后再读到另外的jvm中。那么不可能直接传递普通的Java对象,Java对象只有jvm才有的概念。parcel类似于基本数据的集合,对于传统的系统都是可以管理的。
对于windows系统,进程之间通信完全可以传指针或者数据结构,因为应用之间没有虚拟机的壁垒,大家都是直接和操作系统打交道。
本文深入解析了Android中Parcelable与Serializable接口的区别与应用场景,探讨了两者在数据传输过程中的实现方式及优劣,并针对不同场景提供了实用建议。
653

被折叠的 条评论
为什么被折叠?



