您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > Android

Android数据对象序列化原理与应用

时间:2023-11-14 13:45:29  来源:微信公众号  作者:沐雨花飞蝶

Android数据对象序列化原理与应用

序列化与反序列化

「序列化」是将对象转换为可以存储或传输的格式的过程。在计算机科学中,对象通常是指内存中的数据结构,如数组、列表、字典等。通过序列化,可以将这些对象转换为字节流或文本格式,以便在不同的系统之间进行传输或存储。序列化后的数据可以被传输到远程系统,或者存储在磁盘上,以便在需要时进行读取和恢复。序列化的逆过程称为反序列化,即将序列化后的数据重新转换为原始对象的过程。

「反序列化」是将序列化后的数据恢复为原始对象的过程。在编程中,我们经常需要将对象序列化为字节流或者其他形式的数据,以便在网络传输或者持久化存储中使用。而反序列化则是将这些序列化后的数据重新转换为原始对象。

在不同的编程语言中,反序列化的实现方式可能会有所不同。一般来说,反序列化的过程包括以下几个步骤:

  • 读取序列化后的数据:从文件、网络传输等地方读取序列化后的数据。
  • 解析数据:根据序列化的格式,解析数据并还原为原始的对象结构。
  • 创建对象:根据解析得到的数据,创建对应的对象实例。
  • 恢复对象状态:将解析得到的数据赋值给对象的属性,恢复对象的状态。

反序列化的过程可以用以下伪代码表示:

data = 读取序列化后的数据
object = 解析数据(data)

在实际应用中,反序列化的方式和具体实现会根据编程语言和序列化库的不同而有所差异。不同的序列化格式有不同的特点和适用场景,开发者可以根据具体需求选择合适的序列化方式。

Android数据对象序列化的用途

Android数据对象序列化的主要用途是将对象转换为字节流的形式,以便在网络传输、持久化存储或进程间通信中使用。具体的用途包括:

  • 网络传输:在Android开发中,我们经常需要将对象通过网络传输给其他设备或服务器。通过序列化,我们可以将对象转换为字节流,然后通过网络发送给目标设备或服务器,目标设备或服务器再将字节流反序列化为对象进行处理。
  • 持久化存储:Android应用程序通常需要将数据保存在本地存储中,以便在应用程序关闭后仍然可以访问。通过序列化,我们可以将对象转换为字节流,并将其保存在本地文件或数据库中。当应用程序再次启动时,我们可以将字节流反序列化为对象,以便恢复之前保存的数据。
  • 进程间通信:在Android中,不同的组件(如Activity、Service、BroadcastReceiver等)可能运行在不同的进程中。通过序列化,我们可以将对象转换为字节流,并通过进程间通信机制(如Binder)将字节流传递给其他进程,其他进程再将字节流反序列化为对象进行处理。

序列化提供了一种方便的方式来在不同的场景中传输和存储对象数据。它在网络传输、持久化存储和进程间通信等方面都有广泛的应用。

Android实现对象序列化的方式

在Android中,常用的实现对象序列化有以下几种方式:

(1) 实现Serializable接口:在需要序列化的类中实现Serializable接口,该接口没有任何方法,只是作为一个标记接口。然后使用ObjectOutputStream将对象写入输出流,使用ObjectInputStream从输入流中读取对象。示例代码如下:

public class MyClass implements Serializable {
    // 类的成员变量和方法

    public static void mAIn(String[] args) {
        // 序列化对象
        MyClass obj = new MyClass();
        try {
            FileOutputStream fileOut = new FileOutputStream("object.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(obj);
            out.close();
            fileOut.close();
            System.out.println("对象已序列化");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 反序列化对象
        MyClass newObj = null;
        try {
            FileInputStream fileIn = new FileInputStream("object.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            newObj = (MyClass) in.readObject();
            in.close();
            fileIn.close();
            System.out.println("对象已反序列化");
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

(2) 实现Parcelable接口:Parcelable接口是Android特有的接口,相比Serializable接口,它更高效。在需要序列化的类中实现Parcelable接口,并实现相关方法。然后使用Parcel对象将对象写入Parcel,使用Parcel对象从Parcel中读取对象。示例代码如下:

public class MyClass implements Parcelable {
    // 类的成员变量和方法

    protected MyClass(Parcel in) {
        // 从Parcel中读取数据并赋值给成员变量
    }

    public static final Creator<MyClass> CREATOR = new Creator<MyClass>() {
        @Override
        public MyClass createFromParcel(Parcel in) {
            return new MyClass(in);
        }

        @Override
        public MyClass[] newArray(int size) {
            return new MyClass[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // 将成员变量写入Parcel
    }
}

(3) 使用Gson库:Gson是google提供的一个用于在JAVA对象和JSON数据之间进行序列化和反序列化的库。可以使用Gson将对象转换为JSON字符串,然后再将JSON字符串转换为对象。示例代码如下:

public class MyClass {
    // 类的成员变量和方法

    public static void main(String[] args) {
        // 序列化对象
        MyClass obj = new MyClass();
        Gson gson = new Gson();
        String json = gson.toJson(obj);
        System.out.println("对象已序列化为JSON字符串:" + json);

        // 反序列化对象
        MyClass newObj = gson.fromJson(json, MyClass.class);
        System.out.println("JSON字符串已反序列化为对象");
    }
}

序列化原理

「Serializable」是Java中的一个接口,用于实现对象的序列化和反序列化。序列化是指将对象转换为字节流的过程,而反序列化则是将字节流转换为对象的过程。

Serializable接口没有任何方法,它只是一个标记接口,用于告诉Java虚拟机,该类可以被序列化。要实现序列化,只需要让类实现Serializable接口即可。

在序列化过程中,Java虚拟机会将对象的状态转换为字节序列,然后可以将字节序列保存到文件、数据库或通过网络传输。反序列化过程则是将字节序列重新转换为对象的状态。

在序列化过程中,Java虚拟机会对对象的各个字段进行序列化。对于基本类型和引用类型,Java虚拟机会自动进行序列化。对于自定义类型,需要实现Serializable接口,并且保证该类型的所有成员变量也是可序列化的。

在反序列化过程中,Java虚拟机会根据字节序列重新创建对象,并将字节序列中的数据赋值给对象的各个字段。

需要注意的是,序列化和反序列化的过程中,对象的构造函数不会被调用。因此,在反序列化过程中,如果需要进行一些初始化操作,可以使用特殊的方法readObject()来实现。

总结起来,Serializable接口提供了一种简单的方式来实现对象的序列化和反序列化。通过实现Serializable接口,可以将对象转换为字节序列,以便在不同的环境中进行传输和存储。

「Parcelable」是Android中用于实现对象序列化的接口。它的原理是将对象的数据按照一定的格式进行打包和解包,以便在不同的组件之间传输或存储。

具体实现步骤如下:

  1. 实现Parcelable接口:在需要序列化的类中实现Parcelable接口,并实现其中的方法,包括describeContents()和writeToParcel(Parcel dest, int flags)。
  2. describeContents()方法:该方法返回一个标志位,用于描述Parcelable对象特殊对象的类型。一般情况下,返回0即可。
  3. writeToParcel(Parcel dest, int flags)方法:该方法将对象的数据写入Parcel对象中。在该方法中,需要将对象的各个字段按照一定的顺序写入Parcel对象中,以便在解包时按照相同的顺序读取。
  4. 实现Parcelable.Creator接口:在需要序列化的类中实现Parcelable.Creator接口,并实现其中的方法,包括createFromParcel(Parcel source)和newArray(int size)。
  5. createFromParcel(Parcel source)方法:该方法从Parcel对象中读取数据,并创建出Parcelable对象。在该方法中,需要按照写入Parcel对象时的顺序读取数据,并将其赋值给相应的字段。
  6. newArray(int size)方法:该方法返回一个指定大小的Parcelable数组。

通过实现Parcelable接口,可以将对象的数据打包成一个Parcel对象,然后可以通过Intent传递给其他组件,或者通过Bundle存储到本地。在接收端,可以通过读取Parcel对象的数据,重新构建出原始的对象。

总结起来,Parcelable的原理就是将对象的数据按照一定的格式进行打包和解包,以实现对象的序列化和反序列化。这种方式相对于Java中的Serializable接口,更加高效和灵活。

Serializable/Parcelable对比

Serializable和Parcelable都是用于实现对象的序列化和反序列化的接口,但在实现方式和性能方面有所不同。

(1) Serializable:

  • Serializable是Java提供的默认序列化机制,通过实现Serializable接口,可以将对象转换为字节流,以便在网络传输或保存到文件中。
  • Serializable使用反射机制,将对象的状态保存到字节流中,然后再从字节流中恢复对象的状态。这种方式相对简单,但效率较低。
  • Serializable的缺点是序列化和反序列化的过程需要大量的I/O操作,对性能要求较高的场景下可能会影响程序的执行效率。

(2) Parcelable:

  • Parcelable是Android提供的专门用于Android平台的序列化机制,通过实现Parcelable接口,可以将对象转换为字节流,以便在Activity之间传递。
  • Parcelable使用了更加高效的序列化方式,将对象的状态拆分为多个字段,分别写入和读取字节流。这种方式相对复杂,但效率较高。
  • Parcelable的优点是序列化和反序列化的过程更加高效,对性能要求较高的场景下可以提升程序的执行效率。

Serializable适用于简单的序列化场景,而Parcelable适用于对性能要求较高的Android平台。在选择使用Serializable还是Parcelable时,需要根据具体的需求和性能要求进行权衡。

Android数据对象序列化原理与应用

数据来自parcelable-vs-serializable,实验结果对比Parcelable的效率比Serializable快10倍以上。

总结

对比

Serializable

Parcelable

所属API

Java API

Android SDK API

特点

序列化和反序列化会经过大量的I/O操作,产生大量的临时变量引起GC,且反序列化时需要反射

基于内存拷贝实现的封装和解封(marshalled& unmarshalled),序列化基于Native层实现

开销

相对高

相对低

效率

相对低

相对高

适用场景

简单序列化

Android

在使用「Serializable」进行对象的序列化时,有一些注意点需要注意:

  • 类的定义:被序列化的类需要实现Serializable接口,这是Java提供的一个标记接口,用于表示该类可以被序列化。如果一个类没有实现Serializable接口,那么在进行序列化时会抛出NotSerializableException异常。
  • 成员变量的序列化:被序列化的类的所有成员变量都会被序列化,包括私有成员变量。但是,如果某个成员变量不希望被序列化,可以使用transient关键字进行修饰,被修饰的成员变量在序列化过程中会被忽略。
  • 对象引用的序列化:如果一个类中包含其他对象的引用,那么在序列化时,被引用的对象也会被序列化。但是,如果被引用的对象没有实现Serializable接口,那么在序列化时会抛出NotSerializableException异常。为了解决这个问题,可以将被引用的对象设置为transient,或者让被引用的对象也实现Serializable接口。
  • 序列化版本号:在进行对象的序列化时,会为每个被序列化的类自动生成一个序列化版本号。这个版本号用于在反序列化时判断序列化的类和反序列化的类是否兼容。如果序列化的类和反序列化的类的版本号不一致,会抛出InvalidClassException异常。为了避免这个问题,可以显式地为类指定一个固定的序列化版本号,可以使用serialVersionUID关键字进行指定。
  • 序列化的安全性:在进行对象的序列化时,需要注意序列化的安全性。因为序列化的数据可以被反序列化成对象,如果序列化的数据被篡改,可能会导致安全漏洞。为了增强序列化的安全性,可以使用加密算法对序列化的数据进行加密,或者对序列化的类进行签名验证。

在使用「Parcelable」进行序列化时,有几个注意点需要注意:

  • 实现Parcelable接口:要使一个类可序列化,需要让该类实现Parcelable接口,并实现其中的方法。这些方法包括writeToParcel()和createFromParcel()等。
  • 内部类的序列化:如果要序列化的类中包含内部类,需要确保内部类也实现了Parcelable接口,并在外部类的writeToParcel()和createFromParcel()方法中对内部类进行序列化和反序列化。
  • 序列化顺序:在writeToParcel()方法中,需要按照成员变量的顺序将数据写入Parcel对象。在createFromParcel()方法中,需要按照写入的顺序读取数据。
  • 序列化和反序列化的一致性:在序列化和反序列化过程中,需要确保写入和读取的数据类型一致。例如,如果在writeToParcel()方法中写入了一个整数,那么在createFromParcel()方法中读取时也需要使用相同的方法读取整数。
  • 版本控制:如果在序列化的类中进行了修改,需要注意版本控制。可以通过给类添加一个版本号来实现版本控制,以便在反序列化时能够正确处理不同版本的数据。

使用Parcelable进行序列化时,需要确保实现了Parcelable接口,并注意序列化顺序、内部类的序列化、数据类型的一致性和版本控制等问题。



Tags:Android   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Android Emulator黑屏怎么办 Android模拟器黑屏解决方法
Android Emulator黑屏问题困扰了非常多的玩家,Android Emulator作为一款安卓模拟器,可以让你在电脑上运行和浏览安卓应用程序,但是程序本身不是很稳定,很容易会出现黑屏,启动不了...【详细内容】
2024-03-04  Search: Android  点击:(37)  评论:(0)  加入收藏
Android 谷歌三件套:解锁谷歌生态!
大家是不是遇到这个情况?当我们需要下载一些国外的游戏或者软件的时候,需要在手机里面安装Google Play商店,然后通过Google Play商店下载国外软件!为了帮助大家使用上各种好用的...【详细内容】
2024-01-02  Search: Android  点击:(109)  评论:(0)  加入收藏
Android开发中常见的Hook技术有哪些?
Hook技术介绍Hook技术是一种在软件开发中常见的技术,它允许开发者在特定的事件发生时插入自定义的代码逻辑。常见的应用场景包括在函数调用前后执行特定的操作,或者在特定的事...【详细内容】
2023-12-25  Search: Android  点击:(83)  评论:(0)  加入收藏
在Android应用开发中使用NFC功能
NFC介绍NFC是指“近场通讯”(Near Field Communication),它是一种短距离无线通信技术,允许设备在非接触或极短距离内进行通信。NFC通常用于移动支付、门禁系统、智能标签和其他...【详细内容】
2023-12-22  Search: Android  点击:(102)  评论:(0)  加入收藏
关于Android图像Bitmap类,你要知道的一切
Bitmap介绍Bitmap是一种图像文件格式,它由像素阵列组成,每个像素都有自己的颜色信息。在计算机图形学中,Bitmap图像可以被描述为一个二维的矩阵,其中每个元素代表一个像素的颜色...【详细内容】
2023-12-19  Search: Android  点击:(97)  评论:(0)  加入收藏
Android开发中如何进行单元测试?
单元测试介绍单元测试是软件开发中的一种测试方法,用于验证代码中的最小可测试单元(通常是函数或方法)是否按预期工作。单元测试通常由开发人员编写,旨在隔离和测试代码的特定部...【详细内容】
2023-12-11  Search: Android  点击:(165)  评论:(0)  加入收藏
我的手机我做主,如何为Android手机应用换图标?
作为一名Android用户,你是否曾经为自己的手机桌面感到单调而乏味?虽然Android系统的桌面定制性已经非常强大,但有时候我们还是希望能够在细节上做出一些改变,尤其是对于那些每天...【详细内容】
2023-12-10  Search: Android  点击:(61)  评论:(0)  加入收藏
了解Android系统架构中的HAL硬件抽象层
在Android系统中,HAL的存在使得不同厂商的硬件可以统一被上层的应用程序调用,从而提高了系统的兼容性和可移植性。HAL还可以帮助开发者更方便地开发应用程序,因为他们不需要为...【详细内容】
2023-12-06  Search: Android  点击:(198)  评论:(0)  加入收藏
谷歌 CEO 皮查伊建议 Android 用户不要侧载应用,称非常危险
iOS和Android的一个显著差异是,Android支持用户从第三方渠道安装应用程序(即“侧载”)。然而,谷歌似乎并不希望用户这样做。最近,在与Epic Store的法律诉讼中,谷歌首席执行官桑达...【详细内容】
2023-11-20  Search: Android  点击:(166)  评论:(0)  加入收藏
Android数据对象序列化原理与应用
序列化与反序列化「序列化」是将对象转换为可以存储或传输的格式的过程。在计算机科学中,对象通常是指内存中的数据结构,如数组、列表、字典等。通过序列化,可以将这些对象转换...【详细内容】
2023-11-14  Search: Android  点击:(272)  评论:(0)  加入收藏
▌简易百科推荐
Android Emulator黑屏怎么办 Android模拟器黑屏解决方法
Android Emulator黑屏问题困扰了非常多的玩家,Android Emulator作为一款安卓模拟器,可以让你在电脑上运行和浏览安卓应用程序,但是程序本身不是很稳定,很容易会出现黑屏,启动不了...【详细内容】
2024-03-04  18183游戏网    Tags:Android Emulator   点击:(37)  评论:(0)  加入收藏
Android开发中常见的Hook技术有哪些?
Hook技术介绍Hook技术是一种在软件开发中常见的技术,它允许开发者在特定的事件发生时插入自定义的代码逻辑。常见的应用场景包括在函数调用前后执行特定的操作,或者在特定的事...【详细内容】
2023-12-25  沐雨花飞蝶  微信公众号  Tags:Android   点击:(83)  评论:(0)  加入收藏
在Android应用开发中使用NFC功能
NFC介绍NFC是指“近场通讯”(Near Field Communication),它是一种短距离无线通信技术,允许设备在非接触或极短距离内进行通信。NFC通常用于移动支付、门禁系统、智能标签和其他...【详细内容】
2023-12-22  沐雨花飞蝶  微信公众号  Tags:Android   点击:(102)  评论:(0)  加入收藏
关于Android图像Bitmap类,你要知道的一切
Bitmap介绍Bitmap是一种图像文件格式,它由像素阵列组成,每个像素都有自己的颜色信息。在计算机图形学中,Bitmap图像可以被描述为一个二维的矩阵,其中每个元素代表一个像素的颜色...【详细内容】
2023-12-19  沐雨花飞蝶  微信公众号  Tags:Android   点击:(97)  评论:(0)  加入收藏
Android开发中如何进行单元测试?
单元测试介绍单元测试是软件开发中的一种测试方法,用于验证代码中的最小可测试单元(通常是函数或方法)是否按预期工作。单元测试通常由开发人员编写,旨在隔离和测试代码的特定部...【详细内容】
2023-12-11  沐雨花飞蝶  微信公众号  Tags:Android   点击:(165)  评论:(0)  加入收藏
一篇聊聊Jetpack Room实现数据存储持久性
Room介绍Room 是 Android Jetpack 组件库中的一部分,它是用于在 Android 应用中进行本地数据库访问和管理的库。Room 提供了一个抽象层,使开发者能够更轻松地访问 SQLite 数据...【详细内容】
2023-12-08  沐雨花飞蝶  微信公众号  Tags:Jetpack   点击:(142)  评论:(0)  加入收藏
了解Android系统架构中的HAL硬件抽象层
在Android系统中,HAL的存在使得不同厂商的硬件可以统一被上层的应用程序调用,从而提高了系统的兼容性和可移植性。HAL还可以帮助开发者更方便地开发应用程序,因为他们不需要为...【详细内容】
2023-12-06  沐雨花飞蝶  微信公众号  Tags:Android   点击:(198)  评论:(0)  加入收藏
我们一起聊聊 IntentService 与 Service 的区别?
Service介绍Service组件是Android应用开发中的四大组件之一,用于在后台执行长时间运行的操作或处理远程请求。它可以在没有用户界面的情况下执行任务,并且可以与其他应用组件...【详细内容】
2023-12-06  沐雨花飞蝶  微信公众号  Tags:IntentService   点击:(167)  评论:(0)  加入收藏
Android数据对象序列化原理与应用
序列化与反序列化「序列化」是将对象转换为可以存储或传输的格式的过程。在计算机科学中,对象通常是指内存中的数据结构,如数组、列表、字典等。通过序列化,可以将这些对象转换...【详细内容】
2023-11-14  沐雨花飞蝶  微信公众号  Tags:Android   点击:(272)  评论:(0)  加入收藏
你了解Android中的SELinux吗?
SELinux介绍SELinux(Security-Enhanced Linux)是一种安全增强的Linux操作系统,它通过强制访问控制(MAC)机制来提供更高级别的系统安全保护。相比于传统的Linux访问控制机制(DAC),SEL...【详细内容】
2023-11-09  沐雨花飞蝶  微信公众号  Tags:Android   点击:(263)  评论:(0)  加入收藏
站内最新
站内热门
站内头条