Android kotlin序列化之@Parcelize详解与使用

这篇具有很好参考价值的文章主要介绍了Android kotlin序列化之@Parcelize详解与使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、介绍

        在Android开发过程中,序列化使用概率一直很高。在页面之间传递的对象,需要要使用序列化,常见的序列化:Parcelable、Serialization。

        由于Parcelable在传递压缩比高,效率高,一直被Google官方推荐。在Java语言中,Parcelable可以通过IDE自动生成,但是在kotlin语言下,IDE无法完成自动生成,需要我们手动去填写,而且语言和Java还是有区别。

二、序列化Parcelable

1、插件接入

kotlin在Parcelable的时候需要额外的扩展插件。

新增插件:apply plugin: 'kotlin-android-extensions'

引入插件后,如果你的项目已支持kotlin语言,那就可以正常开发,如果不支持,需要再添加kotlin插件。

三、实战

在kotlin语言中,Parcelable有两种,一种是方法体,还有一种是构造器,而且两种无法混合使用

1、构造器序列化

何为构造器?是将变量申明在构造器中。

@Parcelize
class TestConstructorBean(var name: String = "", var age: Int = 0) : Parcelable 

这种是最简单的,只要继承了Parcelable,类通过@Parcelize申明一下,无须再去编写复杂的映射关系。只需要这么简单的封装即可。

小试牛刀:

Android kotlin序列化之@Parcelize详解与使用

 Android kotlin序列化之@Parcelize详解与使用

如果在方法体中新增字段,是否会序列化成功?

新增字段:

@Parcelize
class TestConstructorBean(var name: String = "", var age: Int = 0) : Parcelable{
    var body:String="default"
}

 入参:

Android kotlin序列化之@Parcelize详解与使用

接收参数:

Android kotlin序列化之@Parcelize详解与使用

分析:

        这个时候,我们会发现,构造器之外的变量都没有值,也就是该字段没有传递过去,在序列化的时候丢失了。所以构造器参数序列化无法将函数体中的变量也添加进去。 

2、函数体序列化

函数体序列化,也就是我们正常定义的,将变量全部在函数体中申明,中没有我们要传递的变量。

新建Bean类:

@Parcelize
class TestBodyParacle() : Parcelable {

    var name: String = ""
    var age: Int = 0


    constructor(parcel: Parcel):this(){
        name=parcel.readString()!!
        age=parcel.readInt()
    }


    companion object : Parceler<TestBodyParacle> {
        override fun create(parcel: Parcel): TestBodyParacle {

            return TestBodyParacle(parcel)
        }

        override fun TestBodyParacle.write(parcel: Parcel, flags: Int) {

            parcel.writeString(name)
            parcel.writeInt(age)
        }
    }

}

同样继承Parcelable 与@Parcelize。

但是,需要重写 Parceler<T>,申明为内部静态,这个T就是当前类,重写create与write两个方法。重写也是可以参考以前。这样就完成了函数体内部的变量序列化。

小试牛刀:

Android kotlin序列化之@Parcelize详解与使用

Android kotlin序列化之@Parcelize详解与使用

 这样我们就完成了基本的数据序列化。

那么函数体支持构造器混合使用嘛?

Android kotlin序列化之@Parcelize详解与使用

Android kotlin序列化之@Parcelize详解与使用

Android kotlin序列化之@Parcelize详解与使用

这个时候,body为空。

如果想构造器参数也参与序列化怎么办?

只需要将构造器参数添加到write与create中,进行序列化即可。

Android kotlin序列化之@Parcelize详解与使用
构造器参数序列化

三、复杂参数序列化

        在实战过程中,Bean的对象不是简单的数据,可能内部已混合了List、map、Bean等数据。这些数据如何参与序列化?

        为什么会特别强调@Parcelize的对象传递?因为Parcelize是通过注解完成的,但是我在测试过程中,发现注解生成有问题,虽然序列化没问题,但是反序列化获取不到对应的值。

        这里面有个BUG,也就是说@Parcelize修复的序列化,如果只是单独的作为一个data可以正常使用,如果作为其他对象的序列化变量,在反序列化时获取不到,但是作为数组类型也是可以获取到的

@Parcelize
class MixParcleEntity() : Parcelable {

    var list = mutableListOf<TestBodyParacle>()
    var entity: TestBodyParacle? = null



    override fun describeContents(): Int {
       return 0
    }

    protected constructor(parcel: Parcel) : this() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            parcel.readParcelableList(list, TestBodyParacle.javaClass.classLoader)
        }
        parcel.readParcelable<TestBodyParacle>(TestBodyParacle.javaClass.classLoader)
    }

    private fun write(parcel: Parcel, flags: Int) {


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            parcel.writeParcelableList(list, flags)

        }
        parcel.writeParcelable(entity, flags)
 


    }


    companion object : Parceler<MixParcleEntity> {
        override fun create(parcel: Parcel): MixParcleEntity {
            return MixParcleEntity(parcel)
        }

        override fun MixParcleEntity.write(parcel: Parcel, flags: Int) {

            write(parcel, flags)
        }
    }

}
Android kotlin序列化之@Parcelize详解与使用
接收页面
Android kotlin序列化之@Parcelize详解与使用
启动页面

反序列化异常分析:

为什么会出现这种情况?正常在JAVA序列化CREATOR,通过这个创建者来完成的,kotlin最终还是要编译成Java文件。但是在编译后,出现了异常,也就是在读写出BUG。

正常kotlin序列化

    companion object {
        @JvmField
        val CREATOR = object : Parcelable.Creator<ParcelableBean> {
            override fun createFromParcel(parcel: Parcel): ParcelableBean {
                return ParcelableBean(parcel)
            }

            override fun newArray(size: Int): Array<ParcelableBean?> {
                return arrayOfNulls(size)
            }
        }
    }
Android kotlin序列化之@Parcelize详解与使用
编译字节码

 kotlin注解异常情况:

   companion object : Parceler<ParcelizeBean> {
        override fun create(parcel: Parcel): ParcelizeBean {

            return ParcelizeBean(parcel)
        }

        override fun ParcelizeBean.write(parcel: Parcel, flags: Int) {

            parcel.writeString(name)
        }
    }

Android kotlin序列化之@Parcelize详解与使用

问题在于Creator生成。这边生成后,在序列化和反序列,调用的ParcelizeBean.Companion.create(in)发生了异常。由于这个文件是自动生成,导致在页面传递出现了异常情况。这种情况只针对单个对象,如果你是数组没有影响

四、复杂数据使用注解序列化方案

有人会问,复杂的数据真的不支持序列化?当然是可以的。但是只能通过构造函数封装数据。

简单数据

@Parcelize
class Student(var name:@RawValue String?="", var map:@RawValue HashMap<*,*>?=null):Parcelable

复杂数据

@Parcelize
class Teacher(var name:String?="",var student: Student?=null,var list:MutableList<Student>?=null):Parcelable

所有需要参与序列化的属性都在构造器中声明

注意:有可能简单数据会报错

Type is not directly supported by ‘Parcelize’ Annotate the parameter type with ‘@RawValue’ if you want it to be serialized using ‘writeValue()’
 

只需要在变量类型前面加上@RawValue

如下:

var name:@RawValue String?="", var map:@RawValue HashMap<*,*>?=null

这样也能解决问题,要保持一致,否则还是会出错。如果不会建议看下面的手动完成序列化

五、总结

1、获取不到数据

        如果在使用过程中,通过注解发生了数据异常,需要检查对象是否序列化了,如果通过构造器的,查看方法体是否参与了,如果是很简单的数据建议构造器,如果是复杂的数据,建议抛弃构造器

2、类中定义子类序列化失败

        如果采用了注解,就不能使用类中定义类这种用法,否则对象获取为null。那用什么?接下来我会介绍抛弃注解,直接使用手写

Android kotlin序列化之Parcelable详解与使用(二)_蜗牛、Z的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-477180.html

到了这里,关于Android kotlin序列化之@Parcelize详解与使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】二叉树篇|超清晰图解和详解:二叉树的序列化和反序列化

    博主简介: 努力学习的22级计算机科学与技术本科生一枚🌸 博主主页: @是瑶瑶子啦 每日一言🌼: 你不能要求一片海洋,没有风暴,那不是海洋,是泥塘——毕淑敏 🍊 序列化 :本质就是 二叉树的遍历 ,就那么几个:前序、中序、后序、层序。而序列化只不过就是 在遍历到

    2024年02月10日
    浏览(40)
  • python序列化和结构化数据详解

    序列化和结构化数据是计算机程序中非常重要的概念,它们的原理和应用在许多应用程序中都是必不可少的。Python作为一种高级编程语言,在序列化和结构化数据方面提供了很多优秀的解决方案。在本文中,我们将详细介绍Python中序列化和结构化数据的相关概念和应用。 1.

    2024年02月08日
    浏览(49)
  • PHP反序列化入门手把手详解

    前言:文章内容大致可分为原理详解-漏洞练习- 防御方法。文章内容偏向于刚接触PHP反序列化的师傅,是一篇对PHP反序列化入门的手把手教学文章。文章特色在于对PHP反序列化原理的详细分析以及一系列由简入深的PHP反序列化习题练习和分析讲解。文章写作初衷是想借助REEBUF平

    2024年02月08日
    浏览(38)
  • 使用nlohmann json库进行序列化与反序列化

    nlohmann源码仓库:https://github.com/nlohmann/json 使用方式:将其nlohmann文件夹加入,包含其头文件json.hpp即可 demo

    2024年02月10日
    浏览(27)
  • SOME/IP协议详解[7 SOME/IP序列化]

    什么是序列化与反序列化? 序列化是指将数据结构或对象按定义的规则转换成二进制串的过程。 反序列化是指将二进制串依据相同规则重新构建成数据结构或对象的过程。 而本质就是一种编码规范。 在SOME/IP中使用序列化的目的和作用? 使数据按照固定格式进行编排成为字

    2024年02月15日
    浏览(24)
  • drf——Request源码分析、序列化组件、序列化类的使用(字段类和参数)、反序列化校验和保存

    views.py中 urls.py中 序列化类 字段 字段构造方式 BooleanField BooleanField() NullBooleanField NullBooleanField() CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) EmailField EmailField(max_length=None, min_length=None, allow_blank=False) RegexField RegexField(regex, max_length=None, min_length=None, a

    2024年02月05日
    浏览(29)
  • 【spark】序列化和反序列化,transient关键字的使用

    Spark是基于JVM运行的进行,其序列化必然遵守Java的序列化规则。 序列化就是指将一个对象转化为二进制的byte流(注意,不是bit流),然后以文件的方式进行保存或通过网络传输,等待被反序列化读取出来。序列化常被用于数据存取和通信过程中 spark dirver和executor间传递变量

    2024年02月10日
    浏览(27)
  • c++ 使用rapidjson对数据序列化和反序列化(vs2109)

      RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库,综合性能是最好的。 1. 安装 在NuGet中为项目安装tencent.rapidjson 2. 引用头文件 #include rapidjson/document.h #include rapidjson/memorystream.h #include rapidjson/prettywriter.h 3. 头文件定义 添加测试json字符串和类型

    2024年02月07日
    浏览(30)
  • 干翻Dubbo系列第九篇:Dubbo体系中序列化详解

    文章目录 文章说明 一:序列化概念 1:概念 2:Dubbo中序列化方式 二:Kyro序列化方案 1:引入依赖 2:XML的配置方式 3:Boot的方式 4:Consumer端调用 三:FST序列化方式使用 1:引入依赖 2:XML的配置方式 3:SpringBoot的配置方式 4: Consumer端调⽤ 序列化是RPC的时候,将需要传输的

    2024年02月13日
    浏览(62)
  • Spring Boot 中使用 ObjectMapper 进行 JSON 序列化和反序列化

    在 Java 中,可以使用各种 JSON 序列化和反序列化工具将 Java 对象转换为 JSON 字符串或者将 JSON 字符串转换为 Java 对象。其中,Jackson 库是比较常用的 JSON 序列化和反序列化工具之一,它提供了 ObjectMapper 类,用于将 Java 对象转换为 JSON 字符串,或者将 JSON 字符串转换为 Java 对象

    2024年02月14日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包