Android 序列化(Serializable和Parcelable)

简介: 🔥 什么是序列化 由于存在于内存中的对象都是暂时的,无法长期驻存,为了把对象的状态保持下来,这时需要把对象写入到磁盘或者其他介质中,这个过程就叫做序列化。🔥 为什么序列化永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中)。对象在网络中传递。对象在IPC间传递。

🔥 什么是序列化


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


🔥 为什么序列化


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


  • 对象在网络中传递。


  • 对象在IPC间传递。


🔥 实现序列化的方式



  • 实现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


import java.io.Serializable;
public class UserSerializable implements Serializable {
    public String name;
    public int age;
}


然后你会发现没有serialVersionUID


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


微信图片_20220524113220.png


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


微信图片_20220524113243.png


效果如下:


public class UserSerializable implements Serializable {
    private static final long serialVersionUID = 1522126340746830861L;
    public String name;
    public int age = 0;
}


💥 实现Parcelable


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


1. public class MyParcelable implements Parcelable {
     private int mData;
     public int describeContents() {
         return 0;
     }
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mData);
     }
     public static final Parcelable.Creator<MyParcelable> CREATOR
             = new Parcelable.Creator<MyParcelable>() {
         public MyParcelable createFromParcel(Parcel in) {
             return new MyParcelable(in);
         }
         public MyParcelable[] newArray(int size) {
             return new MyParcelable[size];
         }
     };
     private MyParcelable(Parcel in) {
         mData = in.readInt();
     }
 }


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


🔥 自动生成 Parcelable


public class User {
    String name;
    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;
    }
}


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


💥 先下载


微信图片_20220524113931.png


💥 使用


微信图片_20220524113953.png


微信图片_20220524114006.png


微信图片_20220524114025.png


💥 效果


public class User implements Parcelable {
    String name;
    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;
    }
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.age);
    }
    public void readFromParcel(Parcel source) {
        this.name = source.readString();
        this.age = source.readInt();
    }
    public User() {
    }
    protected User(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
    }
    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}


 搞定。

       写完了咱就运行走一波。


🔥 使用实例


💥 Serializable


MainActivity.class
        Bundle bundle = new Bundle();
        UserSerializable userSerializable=new UserSerializable("SCC",15);
        bundle.putSerializable("user",userSerializable);
        Intent intent = new Intent(MainActivity.this, BunderActivity.class);
        intent.putExtra("user",bundle);
        startActivity(intent);
BunderActivity.class
        Bundle bundle = getIntent().getBundleExtra("user");
        UserSerializable userSerializable= (UserSerializable) bundle.getSerializable("user");
        MLog.e("Serializable:"+userSerializable.name+userSerializable.age);
日志:
2021-10-25 E/-SCC-: Serializable:SCC15


💥 Parcelable


MainActivity.class
        Bundle bundle = new Bundle();
        bundle.putParcelable("user",new UserParcelable("SCC",15));
        Intent intent = new Intent(MainActivity.this, BunderActivity.class);
        intent.putExtra("user",bundle);
        startActivity(intent);
BunderActivity.class
        Bundle bundle = getIntent().getBundleExtra("user");
        UserParcelable userParcelable= (UserParcelable) bundle.getParcelable("user");
        MLog.e("Parcelable:"+userParcelable.getName()+userParcelable.getAge());
日志:
2021-10-25 E/-SCC-: Parcelable:SCC15


🔥 Parcelable 中使用泛型


💥 UserParcelable


public class UserParcelable<T extends Parcelable> implements Parcelable {
    private String name;
    private int age;
    private T data;
    //...set/get部分省略
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public UserParcelable(String name, int age, T data) {
        this.name = name;
        this.age = age;
        this.data = data;
    }
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.age);
        //这里:先保存这个泛型的类名
        dest.writeString(data.getClass().getName());
        dest.writeParcelable(this.data, flags);
    }
    public void readFromParcel(Parcel source) {
        this.name = source.readString();
        this.age = source.readInt();
        //这里
        String dataName = source.readString();
        try {
            this.data = source.readParcelable(Class.forName(dataName).getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    protected UserParcelable(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
        //这里
        String dataName = in.readString();
        try {
            this.data = in.readParcelable(Class.forName(dataName).getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static final Creator<UserParcelable> CREATOR = new Creator<UserParcelable>() {
        @Override
        public UserParcelable createFromParcel(Parcel source) {
            return new UserParcelable(source);
        }
        @Override
        public UserParcelable[] newArray(int size) {
            return new UserParcelable[size];
        }
    };
}


💥 Tman


public class Tman implements Parcelable {
    String color;
    public Tman(String color) {
        this.color = color;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.color);
    }
    public void readFromParcel(Parcel source) {
        this.color = source.readString();
    }
    protected Tman(Parcel in) {
        this.color = in.readString();
    }
    public static final Creator<Tman> CREATOR = new Creator<Tman>() {
        @Override
        public Tman createFromParcel(Parcel source) {
            return new Tman(source);
        }
        @Override
        public Tman[] newArray(int size) {
            return new Tman[size];
        }
    };
}


💥 使用


MainActivity.class
        Bundle bundle = new Bundle();
        bundle.putParcelable("user",new UserParcelable<>("你好",2021,new Tman("红色")));
        Intent intent = new Intent(MainActivity.this, BunderActivity.class);
        intent.putExtra("user",bundle);
        startActivity(intent);
BunderActivity.class
        Bundle bundle = getIntent().getBundleExtra("user");
        UserParcelable<Tman> userParcelable= (UserParcelable) bundle.getParcelable("user");
        MLog.e("Parcelable:"+userParcelable.getName()+userParcelable.getAge()+userParcelable.getData().getColor());
日志:
2021-10-25 E/-SCC-: Parcelable:你好2021红色


文章知识点与官方知识档案匹配,可进一步学习相关知识

Java技能树IO对象序列化19431 人正在系统学习中

相关文章
|
6月前
|
存储 安全 Java
揭秘Java序列化神器Serializable:一键解锁对象穿越时空的超能力,你的数据旅行不再受限,震撼登场!
【8月更文挑战第4天】Serializable是Java中的魔术钥匙,开启对象穿越时空的能力。作为序列化的核心,它让复杂对象的复制与传输变得简单。通过实现此接口,对象能被序列化成字节流,实现本地存储或网络传输,再通过反序列化恢复原状。尽管使用方便,但序列化过程耗时且存在安全风险,需谨慎使用。
66 7
|
NoSQL Java Redis
[已解决]报异常java.io.InvalidClassException的解决方法|对象序列化实现Serializable会出现java.io.InvalidClassException的异常
[已解决]报异常java.io.InvalidClassException的解决方法|对象序列化实现Serializable会出现java.io.InvalidClassException的异常
|
9月前
|
JSON Android开发 数据格式
android 使用GSON 序列化对象出现字段被优化问题解决方案
android 使用GSON 序列化对象出现字段被优化问题解决方案
149 0
|
9月前
|
存储 Java 开发工具
[Android]序列化原理Parcelable
[Android]序列化原理Parcelable
149 0
|
9月前
|
存储 Java Android开发
[Android]序列化原理Serializable
[Android]序列化原理Serializable
105 0
|
Java Android开发
Android 中通过Intent传递类对象,通过实现Serializable和Parcelable接口两种方式传递对象
Android 中通过Intent传递类对象,通过实现Serializable和Parcelable接口两种方式传递对象
151 1
|
Android开发
Android 中使用Gson进行list集合的序列化与反序列化
Android 中使用Gson进行list集合的序列化与反序列化
211 0
|
JSON Java API
Android 中使用Gson完成对象的序列化与反序列化
Android 中使用Gson完成对象的序列化与反序列化
280 0
|
存储 XML JSON
Android操作配置文件封装类,使用json序列化的方式实现
Android操作配置文件封装类,使用json序列化的方式实现
|
Android开发
AS插件-Android Parcelable code generator.
AS插件-Android Parcelable code generator.
215 0

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Nettyの网络聊天室&扩展序列化算法