android 保存 parcelable对象,Android 使用序列化Serializable和Parcelable

Android 序列化Serializable和Parcelable使用和区别

一:Serializable

1.什么是序列化

将一个类对象转换成可存储,可传输状态的过程。

2.什么是Serializable接口

一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化。

3.为什么要序列化对象

1.把对象转换为字节序列的过程称为对象的序列化

2.把字节序列恢复为对象的过程称为对象的反序列化

4.序列化用途

1.想把对象的状态信息通过网络进行传输

2.需要把对象持久化存储,存储在文件,数据库等public class User implements Serializable {

private static final long serialVersionUID = 1L;

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

当我跟进去,发现Serializable是一个空接口,一个接口什么都没有,我们可以将它理解成一个标识接口例如:在课堂上有位学生遇到一个问题,于是举手向老师请教,这时老师帮他解答,那么这位学生的举手其实就是一个标识,自己解决不了问题请教老师帮忙解决。在Java中的这个Serializable接口其实是给jvm看的,通知jvm,我不对这个类做序列化了,你(jvm)帮我序列化就好了。

49421f206fa19f6dc4e202c4cc8bfc62.png

5.为什么要定义serialVersionUID变量

0c99a6a0016133b2c470334515f48d12.png

从说明中可以看出,如果我们没有自己申明一个serialVersionUID变量,接口会默认生成一个serialVersionUID

*但是强烈建议用户自定义一个serialVersionUID,因为默认的serialVersionUID对于class的细节非常敏感,反序列化时可能会导致

InvalidClassException这个异常。*

5.transient关键字

用来表示一个成员变量不是该对象序列化的一部分。当一个对象被序列化的时候,transient型变量的值不包括在序列化结果中。注:static修饰的静态变量天然的就是不可序列化的private static final long serialVersionUID = 1L;

private String name;

private transient int age;

transient关键字只能修饰变量,而不能修饰方法和类。

被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。

二:Parcelable

Parcelable是Android为我们提供的序列化的接口,Parcelable的效率相对于Serializable也高许多。

Parcelable不能使用在要将数据存储在磁盘上情况

在内存中使用Parcelable性能优于Serializablepublic class User implements Parcelable {

private String name;

private int age;

public User(String name, int age) {

this.name = name;

this.age = age;

}

/**

* 从序列化后的对象中创建原始数据*/

protected User(Parcel in) {

name = in.readString();

age = in.readInt();

}

/**

* 序列化:将当前对象写入序列化结构中

*/

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeString(name);

dest.writeInt(age);

}

/**

* 当前对象的内容描述,存在文件描述符时返回1,其余全返回0

*/

@Override

public int describeContents() {

return 0;

}

/**

* 反序列化

*/

public static final Creator CREATOR = new Creator() {

/**

* 将序列化对象中创建原始数据*/

@Override

public User createFromParcel(Parcel in) {

return new User(in);

}

/**

* 创建指定长度的原始对象数组*/

@Override

public User[] newArray(int size) {

return new User[size];

}

};

@Override

public String toString() {

return "User{" +

"name='" + name + ''' +

", age=" + age +

'}';

}

}

1.Parcel英文译为包裹,Android采用这个词表示封装消息的数据。这个通过IBinder通信的消息载体。Parcel用来存放数据的内存(RAM),而不是永久介质。//获取一个Parcel容器

Parcel parcel=Parcel.obtain();

//需要序列化的对象

User user=new User("mike",13);

//把对象写入Parcel

parcel.writeParcelable(user,0);

//Parcel读写共用一个位置计数,这里一定要重置一下当前的位置

parcel.setDataPosition(0);

//读取Parcel

User user1=parcel.readParcelable(User.class.getClassLoader());

Log.d("LoginActivity",user1.toString());

调用parcel.writeParcelable(user,0);源码解析public final void writeParcelable(@Nullable Parcelable p, int parcelableFlags) {

//判断p是否为空

if (p == null) {

writeString(null);

return; }

//先写入P的类名(user就是p类类名)

writeParcelableCreator(p);

//调用我们重写的writeToParcel方法,按顺序写入

p.writeToParcel(this, parcelableFlags);

}

/** @hide */

@UnsupportedAppUsage

public final void writeParcelableCreator(@NonNull Parcelable p) {

//写入p类的类名

String name = p.getClass().getName();

writeString(name);

}

调用parcel.readParcelable(User.class.getClassLoader());源码解析public final T readParcelable(@Nullable ClassLoader loader) {

//调用readParcelableCreator

//这时我们获取就是我们自定义的CREATOR

Parcelable.Creator> creator = readParcelableCreator(loader);

if (creator == null) {

return null;

}

// 判断当前creator是不是Parcelable.ClassLoaderCreator>的实例

if (creator instanceof Parcelable.ClassLoaderCreator>) {

//如果是的话,,我们调用reateFromParcel(this, loader)

Parcelable.ClassLoaderCreator> classLoaderCreator =

(Parcelable.ClassLoaderCreator>) creator;

return (T) classLoaderCreator.createFromParcel(this, loader);

}

//调用我们自定义的CREATOR中重写的createFromParcel方法

return (T) creator.createFromParcel(this);

}public final Parcelable.Creator> readParcelableCreator(@Nullable ClassLoader loader) {

//首先把类名读取出来

String name = readString();

if (name == null) {

return null;

}

Parcelable.Creator> creator;

//mCreators做了一下缓存,如果之前某个classloader把一个parcelable的Creator获取过

//那么就不需要通过反射去查找了

synchronized (mCreators) {

HashMap> map = mCreators.get(loader);

if (map == null) {

map = new HashMap<>();

mCreators.put(loader, map);

}

creator = map.get(name);

if (creator == null) {

try {

// If loader == null, explicitly emulate Class.forName(String) "caller

// classloader" behavior. ClassLoader parcelableClassLoader =

(loader == null ? getClass().getClassLoader() : loader);

// Avoid initializing the Parcelable class until we know it implements

// Parcelable and has the necessary CREATOR field. http://b/1171613. Class> parcelableClass = Class.forName(name, false /* initialize */,

parcelableClassLoader);

if (!Parcelable.class.isAssignableFrom(parcelableClass)) {

throw new BadParcelableException("Parcelable protocol requires subclassing "

+ "from Parcelable on class " + name);

}

Field f = parcelableClass.getField("CREATOR");

if ((f.getModifiers() & Modifier.STATIC) == 0) {

throw new BadParcelableException("Parcelable protocol requires "

+ "the CREATOR object to be static on class " + name);

}

Class> creatorType = f.getType();

if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {

// Fail before calling Field.get(), not after, to avoid initializing

// parcelableClass unnecessarily. throw new BadParcelableException("Parcelable protocol requires a "

+ "Parcelable.Creator object called "

+ "CREATOR on class " + name);

}

creator = (Parcelable.Creator>) f.get(null);

}

catch (IllegalAccessException e) {

Log.e(TAG, "Illegal access when unmarshalling: " + name, e);

throw new BadParcelableException(

"IllegalAccessException when unmarshalling: " + name);

}

catch (ClassNotFoundException e) {

Log.e(TAG, "Class not found when unmarshalling: " + name, e);

throw new BadParcelableException(

"ClassNotFoundException when unmarshalling: " + name);

}

catch (NoSuchFieldException e) {

throw new BadParcelableException("Parcelable protocol requires a "

+ "Parcelable.Creator object called "

+ "CREATOR on class " + name);

}

if (creator == null) {

throw new BadParcelableException("Parcelable protocol requires a "

+ "non-null Parcelable.Creator object called "

+ "CREATOR on class " + name);

}

map.put(name, creator);

}

}

return creator;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值