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

news2024/11/28 12:33:45

一、介绍

        在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申明一下,无须再去编写复杂的映射关系。只需要这么简单的封装即可。

小试牛刀:

 

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

新增字段:

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

 入参:

接收参数:

分析:

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

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两个方法。重写也是可以参考以前。这样就完成了函数体内部的变量序列化。

小试牛刀:

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

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

这个时候,body为空。

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

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

构造器参数序列化

三、复杂参数序列化

        在实战过程中,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)
        }
    }

}

接收页面

启动页面

反序列化异常分析:

为什么会出现这种情况?正常在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)
            }
        }
    }
编译字节码

 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)
        }
    }

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

四、总结

1、获取不到数据

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

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

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

https://blog.csdn.net/qq36246172/article/details/131131893

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/628650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

可调电阻器

1、可调电阻&#xff08;Trimming Potentiometer&#xff0c;Variable Resistor&#xff09; 1.1、电气特性&#xff08;Electrical Characteristics&#xff09; ItemSpec ExampleDescriptionTotal Resistance&#xff08;TR&#xff09;&#xff0c;总和阻抗200K端子1和3之间…

独立按键检测短按、长按,松手后响应操作

背景 有项目使用独立按键检测&#xff0c;短按、长按。根据使用效果&#xff0c;发现松手后&#xff0c;也就是按键弹起后响应操作比较好操作。 记得之前&#xff0c;博主写过一篇关于按键的检测的文章&#xff0c;但是过于复杂了。可能很难懂&#xff0c;这里就简单一点&…

Flask学习-环境配置

目录 一.环境部署 二.Flask基本结构 三.完整代码 四.运行效果 一.环境部署 在安装好python&#xff0c;pip环境的基础上在命令行输入如下指令&#xff1a; pip install flask flask框架即安装完毕。 二.Flask基本结构 flask的使用通过创建实例实现。创建方法如下&…

ArgoCD(五)----ArgoCD 各CRD资源配置文件规范

3.4.1 Application资源规范 Application CRD的spec字段主要嵌套如下几个字段&#xff1a; source &#xff1a;配置仓库及相关的配置访问及使用方法&#xff1b;支持如下几种类型&#xff1a; kubernetets的原生配置文件Helm chartkustomize&#xff1a;由kustomize字段进行定义…

软件测试实战,支付二维码测试-测试点汇总,全面覆盖...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 面试的时候&#…

递归——先递后归——平衡二叉树

目录 1.什么是递归 &#xff08;1&#xff09;问问无所不能的chatgpt。 ​&#xff08;2&#xff09;我的理解 2.递归的应用之——树 &#xff08;1&#xff09;二叉树的录入与打印 &#xff08;2&#xff09;举个例子&#xff1a;将有序的数组转化为平衡二叉树 1.什么是递…

ffmpeg中的avs解码器综述

最近拿了一个avs的视频流&#xff0c;用硬件可以解码&#xff0c;但是ffmpeg自带的却无法解码。 所以研究了一下&#xff0c;首先看ffmpeg的avs解码器&#xff1a; 可以看到avs有两个&#xff0c;第一个是avs 第二个是cavs. 我们先用avs来解码&#xff0c;解码的视频是通过【a…

浅谈医院能耗监控平台研究与应用

摘要&#xff1a;综合性医院作为大型公共机构&#xff0c;能耗高的问题日益突出&#xff0c;构建能耗监控平台对医院能耗量化管理以及效果评估已经成为迫切需要。建立智能能耗监控平台&#xff0c;对采集的能耗数据进行分析&#xff0c;实现对医院能耗平台监控&#xff0c;为医…

java并发编程:Fork/Join并发框架介绍

文章目录 Fork/Join简介工作窃取算法Fork/Join的具体实现ForkJoinTaskfork()方法join()方法 ForkJoinPoolWorkQueuerunState Fork/Join的异常处理Fork/Join的使用 Fork/Join简介 Fork/Join框架是一个实现了ExecutorService接口的多线程处理器&#xff0c;它专为那些可以通过递…

java的内部类

1.内部类的概念 内部类表示的事物是外部类的一部分&#xff0c;内部类单独出现没有任何意义。如发动机是汽车的一部分。 内部类的访问特点&#xff1a; &#xff08;1&#xff09;内部类可以直接访问外部类的成员&#xff0c;包括私有&#xff1b; &#xff08;2&#xff09;外…

11.无监督学习之主成分分析

11.1 降维 降维的两种应用&#xff1a;一是数据压缩&#xff1b;二是可视化数据。 11.1.1 数据压缩 将相关性强的两个特征导致冗余&#xff0c;可以直接去掉其中一个特征&#xff0c;或者将两个特征进行某种转换&#xff0c;得到一个特征。 11.1.2 可视化数据 直接看数据可…

设计模式:提升软件设计质量的利器,适合入门者的指南

目录 导言&#xff1a;设计模式的概念常见的设计模式2.1. 单例模式&#xff08;Singleton Pattern&#xff09;2.2. 工厂模式&#xff08;Factory Pattern&#xff09;2.3. 观察者模式&#xff08;Observer Pattern&#xff09;2.4. 策略模式&#xff08;Strategy Pattern&…

OpenGL 摄像机

1.简介 OpenGL本身没有摄像机(Camera)的概念&#xff0c;但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机&#xff0c;产生一种我们在移动的感觉&#xff0c;而不是场景在移动。 要定义一个摄像机&#xff0c;我们需要它在世界空间中的位置、观察的方向…

Java 实现在顺序表中获取 pos 元素的位置

一、思路 1.顺序表不能是空的 2.pos位置要合法 3.直接返回当前的pos位置的下标 二、图解 返回的要是当前 pos 位置的下标&#xff0c;因为下标是没有负数的&#xff0c;由此就可以得出如果下标是负数的话&#xff0c; 这就是一种不合法的情况。 pos 位置的下标也不会超过顺序…

星空特效,截图不太完美

先上效果&#xff1a; 再上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>星空</title><meta name"viewport" content"widthdevice-width, user-scalable…

【立体视觉(三)】之张正友标定法原理

【立体视觉&#xff08;三&#xff09;】之张正友标定法原理 一、相机标定二、参数求解一&#xff09;闭合解二&#xff09;极大似然解三&#xff09;考虑相机畸变 三、实验流程 此为个人学习笔记&#xff0c;在各处借鉴了不少好图好文&#xff08;参考文献在文末&#xff09;&…

项目中常用的linux命令总结大全

哈喽 大家好啊&#xff0c;相信大家在项目中都会常常部署服务器&#xff0c;就涉及到一些常见的linux命令了 1.命令提示符表示命令输入 ps aux | grep nginx&#xff08;查看nginx进程运行状态&#xff09;whereis nginx 查找哪里有nginxlsof -i:5300 查看端口状态kill -9 xxx进…

攻防世界-Crypto-转轮机加密

1. 题目如下&#xff1a; 1: < ZWAXJGDLUBVIQHKYPNTCRMOSFE < 2: < KPBELNACZDTRXMJQOYHGVSFUWI < 3: < BDMAIZVRNSJUWFHTEQGYXPLOCK < 4: < RPLNDVHGFCUKTEBSXQYIZMJWAO < 5: < IHFRLABEUOTSGJVDKCPMNZQWXY < 6: < AMKGHIWPNYCJBFZDR…

大数据需要学习哪些内容?

大数据技术的体系庞大且复杂&#xff0c;每年都会涌现出大量新的技术&#xff0c;目前大数据行业所涉及到的核心技术主要就是&#xff1a;数据采集、数据存储、数据清洗、数据查询分析和数据可视化。 Python 已成利器 在大数据领域中大放异彩 Python&#xff0c;成为职场人追求…

论文阅读和分析:Binary CorNET Accelerator for HR Estimation From Wrist-PPG

主要贡献&#xff1a; 一种完全二值化网络(bCorNET)拓扑结构及其相应的算法-架构映射和高效实现。对CorNET进行量化后&#xff0c;减少计算量&#xff0c;又能实现减轻运动伪影的效果。 该框架在22个IEEE SPC受试者上的MAE为6.675.49 bpm。该设计采用ST65 nm技术框架&#xff…