Android 序列化(Serializable和Parcelable)

举报
帅次 发表于 2021/12/23 01:28:07 2021/12/23
【摘要】 🔥 什么是序列化         由于存在于内存中的对象都是暂时的,无法长期驻存,为了把对象的状态保持下来,这时需要把对象写入到磁盘或者其他介质中,这个过程就叫做序列化。 🔥 为什么序列化 永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘...

🔥 什么是序列化

        由于存在于内存中的对象都是暂时的,无法长期驻存,为了把对象的状态保持下来,这时需要把对象写入到磁盘或者其他介质中,这个过程就叫做序列化。

🔥 为什么序列化

  • 永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中)。

  • 对象在网络中传递。

  • 对象在IPC间传递。

🔥 实现序列化的方式

  • 实现Serializable接口

  • 实现Parcelable接口

🔥 Serializable 和 Parcelable 区别

  • Serializable 是Java本身就支持的接口。

  • Parcelable 是Android特有的接口,效率比实现Serializable接口高效(可用于Intent数据传递,也可以用于进程间通信(IPC))。

  • Serializable的实现,只需要implements Serializable即可。这只是给对象打了一个标记,系统会自动将其序列化。

  • Parcelabel的实现,不仅需要implements Parcelabel,还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator接口。

  • Serializable 使用I/O读写存储在硬盘上,而Parcelable是直接在内存中读写。

  • Serializable会使用反射,序列化和反序列化过程需要大量I/O操作,Parcelable 自己实现封送和解封( marshalled &unmarshalled)操作不需要用反射,数据也存放在Native内存中,效率要快很多

💥 实现Serializable


  
  1. import java.io.Serializable;
  2. public class UserSerializable implements Serializable {
  3.     public String name;
  4.     public int age;
  5. }

        然后你会发现没有serialVersionUID

        Android Studio 是默认关闭 serialVersionUID 生成提示的,我们需要打开Setting,执行如下操作:

        再次回到UserSerializable类,有个提示,就可以添加serialVersionUID了。

 

        效果如下:


  
  1. public class UserSerializable implements Serializable {
  2.     private static final long serialVersionUID = 1522126340746830861L;
  3.     public String name;
  4.     public int age = 0;
  5.     
  6. }

💥 实现Parcelable

        Parcelabel的实现,不仅需要实现Parcelabel接口,还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator 接口,并实现读写的抽象方法。如下:


  
  1.  public class MyParcelable implements Parcelable {
  2.      private int mData;
  3.      public int describeContents() {
  4.          return 0;
  5.      }
  6.      public void writeToParcel(Parcel out, int flags) {
  7.          out.writeInt(mData);
  8.      }
  9.      public static final Parcelable.Creator<MyParcelable> CREATOR
  10.              = new Parcelable.Creator<MyParcelable>() {
  11.          public MyParcelable createFromParcel(Parcel in) {
  12.              return new MyParcelable(in);
  13.          }
  14.          public MyParcelable[] newArray(int size) {
  15.              return new MyParcelable[size];
  16.          }
  17.      };
  18.      private MyParcelable(Parcel in) {
  19.          mData = in.readInt();
  20.      }
  21.  }

        此时Android Studio 给我们了一个插件可自动生成Parcelable 。

🔥 自动生成 Parcelable


  
  1. public class User {
  2.     String name;
  3.     int age;
  4.     public String getName() {
  5.         return name;
  6.     }
  7.     public void setName(String name) {
  8.         this.name = name;
  9.     }
  10.     public int getAge() {
  11.         return age;
  12.     }
  13.     public void setAge(int age) {
  14.         this.age = age;
  15.     }
  16. }

想进行序列化,但是自己写太麻烦了,这里介绍个插件操作简单易上手。

💥 先下载

 

💥 使用

 

 

 

💥 效果


  
  1. public class User implements Parcelable {
  2.     String name;
  3.     int age;
  4.     public String getName() {
  5.         return name;
  6.     }
  7.     public void setName(String name) {
  8.         this.name = name;
  9.     }
  10.     public int getAge() {
  11.         return age;
  12.     }
  13.     public void setAge(int age) {
  14.         this.age = age;
  15.     }
  16.     @Override
  17.     public int describeContents() {
  18.         return 0;
  19.     }
  20.     @Override
  21.     public void writeToParcel(Parcel dest, int flags) {
  22.         dest.writeString(this.name);
  23.         dest.writeInt(this.age);
  24.     }
  25.     public void readFromParcel(Parcel source) {
  26.         this.name = source.readString();
  27.         this.age = source.readInt();
  28.     }
  29.     public User() {
  30.     }
  31.     protected User(Parcel in) {
  32.         this.name = in.readString();
  33.         this.age = in.readInt();
  34.     }
  35.     public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
  36.         @Override
  37.         public User createFromParcel(Parcel source) {
  38.             return new User(source);
  39.         }
  40.         @Override
  41.         public User[] newArray(int size) {
  42.             return new User[size];
  43.         }
  44.     };
  45. }

        搞定。

        写完了咱就运行走一波。

🔥 使用实例

💥 Serializable


  
  1. MainActivity.class
  2.         Bundle bundle = new Bundle();
  3.         UserSerializable userSerializable=new UserSerializable("SCC",15);
  4.         bundle.putSerializable("user",userSerializable);
  5.         Intent intent = new Intent(MainActivity.this, BunderActivity.class);
  6.         intent.putExtra("user",bundle);
  7.         startActivity(intent);
  8.         
  9. BunderActivity.class
  10.         Bundle bundle = getIntent().getBundleExtra("user");
  11.         UserSerializable userSerializable= (UserSerializable) bundle.getSerializable("user");
  12.         MLog.e("Serializable:"+userSerializable.name+userSerializable.age);
  13.         
  14. 日志:
  15. 2021-10-25 E/-SCC-: Serializable:SCC15

💥 Parcelable


  
  1. MainActivity.class
  2.         Bundle bundle = new Bundle();
  3.         bundle.putParcelable("user",new UserParcelable("SCC",15));
  4.         Intent intent = new Intent(MainActivity.this, BunderActivity.class);
  5.         intent.putExtra("user",bundle);
  6.         startActivity(intent);
  7.         
  8. BunderActivity.class
  9.         Bundle bundle = getIntent().getBundleExtra("user");
  10.         UserParcelable userParcelable= (UserParcelable) bundle.getParcelable("user");
  11.         MLog.e("Parcelable:"+userParcelable.getName()+userParcelable.getAge());
  12.         
  13. 日志:
  14. 2021-10-25 E/-SCC-: Parcelable:SCC15

🔥 Parcelable 中使用泛型

💥 UserParcelable


  
  1. public class UserParcelable<T extends Parcelableimplements Parcelable {
  2.     private String name;
  3.     private int age;
  4.     private T data;
  5.     //...set/get部分省略
  6.     public T getData() {
  7.         return data;
  8.     }
  9.     public void setData(T data) {
  10.         this.data = data;
  11.     }
  12.     public UserParcelable(String name, int age, T data) {
  13.         this.name = name;
  14.         this.age = age;
  15.         this.data = data;
  16.     }
  17.     @Override
  18.     public int describeContents() {
  19.         return 0;
  20.     }
  21.     @Override
  22.     public void writeToParcel(Parcel dest, int flags) {
  23.         dest.writeString(this.name);
  24.         dest.writeInt(this.age);
  25.         //这里:先保存这个泛型的类名
  26.         dest.writeString(data.getClass().getName());
  27.         dest.writeParcelable(this.data, flags);
  28.     }
  29.     public void readFromParcel(Parcel source) {
  30.         this.name = source.readString();
  31.         this.age = source.readInt();
  32.         //这里
  33.         String dataName = source.readString();
  34.         try {
  35.             this.data = source.readParcelable(Class.forName(dataName).getClassLoader());
  36.         } catch (ClassNotFoundException e) {
  37.             e.printStackTrace();
  38.         }
  39.     }
  40.     protected UserParcelable(Parcel in) {
  41.         this.name = in.readString();
  42.         this.age = in.readInt();
  43.         //这里
  44.         String dataName = in.readString();
  45.         try {
  46.             this.data = in.readParcelable(Class.forName(dataName).getClassLoader());
  47.         } catch (ClassNotFoundException e) {
  48.             e.printStackTrace();
  49.         }
  50.     }
  51.     public static final Creator<UserParcelable> CREATOR = new Creator<UserParcelable>() {
  52.         @Override
  53.         public UserParcelable createFromParcel(Parcel source) {
  54.             return new UserParcelable(source);
  55.         }
  56.         @Override
  57.         public UserParcelable[] newArray(int size) {
  58.             return new UserParcelable[size];
  59.         }
  60.     };
  61. }

💥 Tman


  
  1. public class Tman implements Parcelable {
  2.     String color;
  3.     public Tman(String color) {
  4.         this.color = color;
  5.     }
  6.     public String getColor() {
  7.         return color;
  8.     }
  9.     public void setColor(String color) {
  10.         this.color = color;
  11.     }
  12.     @Override
  13.     public int describeContents() {
  14.         return 0;
  15.     }
  16.     @Override
  17.     public void writeToParcel(Parcel dest, int flags) {
  18.         dest.writeString(this.color);
  19.     }
  20.     public void readFromParcel(Parcel source) {
  21.         this.color = source.readString();
  22.     }
  23.     protected Tman(Parcel in) {
  24.         this.color = in.readString();
  25.     }
  26.     public static final Creator<Tman> CREATOR = new Creator<Tman>() {
  27.         @Override
  28.         public Tman createFromParcel(Parcel source) {
  29.             return new Tman(source);
  30.         }
  31.         @Override
  32.         public Tman[] newArray(int size) {
  33.             return new Tman[size];
  34.         }
  35.     };
  36. }

💥 使用


  
  1. MainActivity.class
  2.         Bundle bundle = new Bundle();
  3.         bundle.putParcelable("user",new UserParcelable<>("你好",2021,new Tman("红色")));
  4.         Intent intent = new Intent(MainActivity.this, BunderActivity.class);
  5.         intent.putExtra("user",bundle);
  6.         startActivity(intent);
  7.         
  8. BunderActivity.class
  9.         Bundle bundle = getIntent().getBundleExtra("user");
  10.         UserParcelable<Tman> userParcelable= (UserParcelable) bundle.getParcelable("user");
  11.         MLog.e("Parcelable:"+userParcelable.getName()+userParcelable.getAge()+userParcelable.getData().getColor());
  12.         
  13. 日志:
  14. 2021-10-25 E/-SCC-: Parcelable:你好2021红色

文章来源: shuaici.blog.csdn.net,作者:帅次,版权归原作者所有,如需转载,请联系作者。

原文链接:shuaici.blog.csdn.net/article/details/121008960

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。