Android 开发 Parcelable,Serializable接口
Activity之间传数据时,为了避免麻烦,往往会将一些值封装成对象,然后将整个对象传递过去。
对于Android来说传递复杂类型,主要是将自己的类转换为基础的字节数组,Activity之间传递数据是通过Intent实现的。
Android序列化对象主要有两种方法,实现Serializable接口、或者实现Parcelable接口。实现Serializable接口是Java SE本身就支持
的,而Parcelable是Android特有的功能,效率比实现Serializable接口高,而且还可以用在进程间通信(IPC)中。
实现Serializable接口非常简单,声明一下就可以了。而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。
a)当你想把的内存中的对象写入到硬盘的时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
再稍微解释一下:
a)比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到
内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把
它拿出来用,那么这时候就要实现Serializable接口;
b)在进行java的Socket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口;
最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,所以可以在网络上传输。
c)如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,
那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。
1、什么是Parcelable接口呢?
1)Parcelable,定义了将数据写入Parcel,和从Parcel中读出的接口。一个实体(用类来表示),如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为“可打包的”了。
2)Parcelable接口的定义:
- public interface Parcelable {
- //内容描述接口,基本不用管
- public int describeContents();
- //写入接口函数,打包
- public void writeToParcel(Parcel dest, int flags);
- //读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,
- <span style="font-family:Arial;"> </span>//继承类名通过模板参数传入。
- //为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例。
- public interface Creator<T> {
- public T createFromParcel(Parcel source);
- public T[] newArray(int size);
- }
- }
二 至于选取哪种可参考下面的原则:
1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。
Parcelable接口的作用:实现了Parcelable接口的实例可以将自身的状态信息(状态信息通常指的是各成员变量的值)写入Parcel,
也可以从Parcel中恢复其状态。 Parcel用来完成数据的序列化传递。下面就介绍一下实现Parcelable接口的方法。
通过实现Parcelable接口序列化对象的步骤:
1、实现Parcelable接口。
2、并且实现Parcelable接口的public void writeToParcel(Parcel dest, int flags)方法 。
3、自定义类型中必须含有一个名称为CREATOR的静态成员,该成员对象要求实现Parcelable.Creator接口及其方法。
简而言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。
也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程
需要你来实现,因此写的顺序和读的顺序必须一致。
示例代码:
- package com.yang.domain;
- import android.os.Parcel;
- import android.os.Parcelable;
- public class Person implements Parcelable {
- //这里定义了两个变量来说明读和写的顺序要一致
- private Integer id;
- private String name;
- public Person() {
- }
- public Person(Integer id, String name) {
- this.id = id;
- this.name = name;
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @Override
- public int describeContents() {
- return 0;
- }
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- // 把javanbean中的数据写到Parcel。先写id然后写name
- dest.writeInt(this.id);
- dest.writeString(this.name);
- }
- // 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口
- public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
- @Override
- public Person createFromParcel(Parcel source) {
- // 从Parcel中读取数据,返回person对象
- return new Person(source.readInt(), source.readString());
- }
- @Override
- public Person[] newArray(int size) {
- return new Person[size];
- }
- };
- }
要传递的数据是由复制数据类型组合而成时:
- public class MyParcelable implements Parcelable {
- private List<MyListClass> arrList = new ArrayList<MyListClass>();
- private int myInt = 0;
- private String str = null;
- public String getStr() {
- return str;
- }
- public void setStr(String str) {
- this.str = str;
- }
- public List<MyListClass> getArrList() {
- return arrList;
- }
- public void setArrList(List<MyListClass> arrList) {
- this.arrList = arrList;
- }
- public int getMyInt() {
- return myInt;
- }
- public void setMyInt(int myInt) {
- this.myInt = myInt;
- }
- MyParcelable() {
- // initialization
- arrList = new ArrayList<MyListClass>();
- }
- public MyParcelable(Parcel in) {
- myInt = in.readInt();
- str = in.readString();
- in.readTypedList(arrList, MyListClass.CREATOR);
- }
- @Override
- public int describeContents() {
- return 0;
- }
- @Override
- public void writeToParcel(Parcel outParcel, int flags) {
- outParcel.writeInt(myInt);
- outParcel.writeString(str);
- outParcel.writeTypedList(arrList);
- }
- public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
- @Override
- public MyParcelable createFromParcel(Parcel in) {
- return new MyParcelable(in);
- }
- @Override
- public MyParcelable[] newArray(int size) {
- return new MyParcelable[size];
- }
- };
- }
当有子类父类情况时:
- public abstract class A implements Parcelable {
- private int a;
- protected A(int a) {
- this.a = a;
- }
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(a);
- }
- protected A(Parcel in) {
- a = in.readInt();
- }
- }
- public class B extends A {
- private int b;
- public B(int a, int b) {
- super(a);
- this.b = b;
- }
- public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() {
- public B createFromParcel(Parcel in) {
- return new B(in);
- }
- public B[] newArray(int size) {
- return new B[size];
- }
- };
- public int describeContents() {
- return 0;
- }
- public void writeToParcel(Parcel out, int flags) {
- super.writeToParcel(out, flags);
- out.writeInt(b);
- }
- private B(Parcel in) {
- super(in);
- b = in.readInt();
- }
- }
2、什么是Serializable接口?
1)一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。
2)如何实现Serializable接口?
很简单,只要implements Serializable接口就可以了
3)代码实现>
- package com.jyxp.my.parcelable;
- import java.io.Serializable;
- public class MySerializable implements Serializable {
- private static final long serialVersionUID = 1L;
- private Double mDouble;
- private Float mFloat;
- public MySerializable() {
- // TODO Auto-generated constructor stub
- }
- public Double getmDouble() {
- return mDouble;
- }
- public void setmDouble(Double mDouble) {
- this.mDouble = mDouble;
- }
- public Float getmFloat() {
- return mFloat;
- }
- public void setmFloat(Float mFloat) {
- this.mFloat = mFloat;
- }
- }
3、如何实现传值
1)基本数据类型,自身可以
2)传递Serializable对象时,被传递的Serializable对象里面的自定义成员对象(非API中的Serializable对象)也要实现
Serializable接口,否则会出现Caused by: java.io.NotSerializableException异常。从上面的代码可以看出,
在Parcelable对象中是可以传递Serializable对象的,但Serializable对象里面传递的时候可不可以有Parcelable?
回答是否定的,一样会产生java.io.NotSerializableException异常.
3)android api中只能传递Parcelable对象的集合,而不能传递Serializable对象的集合,也就是只能传递
ArrayList<Bitmap>,却不能传递ArrayList<Designer>。刚刚开始学android的时候,对象都是被封装成Serializable,
再传递,因为Serializable是JAVASE里面的本地化接口,很熟悉,当时也产生疑问,为什么会有Parcelable接口,
这两个有什么区别?到后来,当Serializable不能满足要求的时候就明白了,android利用Pacelable对自己的东西进行
封装,就像Worker中的Bitmap,在read的时候可以不需要设置ClassLoader。
4)也是可以传递枚举enum的,把枚举当做类来看就行了。
Android 开发 Parcelable,Serializable接口相关推荐
- Android开发之通过接口回调机制加载数据(源代码分享)
Android开发之通过接口回调机制加载数据的简单实现,在实际开发中通过callback方法得到网络加载的数据的使用频率远比通过直接开启线程或异步任务加载数据的频率高的多,这篇文章的代码将简单实现该机 ...
- android开发接口调用,Android开发中webService接口调用示例
代码示例: package com.study.ws; import java.io.IOException; import org.ksoap2.SoapEnvelope; import org.k ...
- android开发股票数据接口,股票数据接口-股票数据接口api
原标题:股票数据接口-股票数据接口api 量亿数据专注金融领域API数据接口,其中包括期货.股票.期权.外汇等,只需要注册即可申请使用. 免费申请网址:http://www.liangyee.com/ ...
- Android --- Serializable 接口与 Parcelable 接口的使用方法和区别,怎么选择?
文章目录 一.前言: 二.Serializable 接口 三.Parcelable 接口 四.两种接口怎么选择 一.前言: 本节主要讲解 IPC 中的基本概念,Serializable 接口与 Par ...
- Android中Parcelable与Serializable接口用法
转自: Android中Parcelable接口用法 1. Parcelable接口 Interface for classes whose instances can be written to a ...
- android数据回传的代码,android Activity之间数据传递 Parcelable和Serializable接口的使用...
Activity之间传数据时,为了避免麻烦,往往会将一些值封装成对象,然后将整个对象传递过去.传对象的时候有两种情况,一种是实现Parcelable接口,一种是实现Serializable接口. 0. ...
- Android中Parcelable接口用法 和 Serializable实现与Parcelabel实现的区别
1. Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel. ...
- android 传递接口对象吗,android中Intent传递对象,需要实现Serializable接口或者Parcelable接口...
Intent传递对象,有两种方法 1. 实现Serializable接口 类要生成序列化ID,并且不能是内部类 2. 实现Parcelable接口 参照Parcelable的doc文档 实现Seria ...
- Serializable接口和Parcelable接口
一.Serializable接口 在Java中,一般在定义实体类(entity class)时,会去实现Serializable接口,下面举例: 重点: 使用Serializable接口很简单,只需要 ...
最新文章
- linux永久改变字符集,Linux 下mysql永久更改字符集
- Lua require 相对路径
- R中6种读入表格数据的方式哪个最快?结果出人意料!
- 基于OK6410开发板Uboot源码简单分析
- 少林寺步入 5G 时代!
- python是什么编程语言-Python是什么?可能是最受欢迎的编程语言
- 自立,霸者的生存之道
- Linux学习笔记B站狂神说(自己总结方便复习)
- 中国大陆身份证正则表达式(严格验证省份和日期)
- python 100days github_GitHub - 1042970366/Python-100-Days: Python - 100天从新手到大师
- 涨分神器-基于PPYOLOE的切图和拼图解决方案
- python音频 降噪_python - 使用pyaudio对音频播放进行降噪 - 堆栈内存溢出
- python api调用 验证码_Python语言调用创蓝253短信验证码API文档
- ps界面为啥突然变大了_对新手非常友好的5个PS小技巧
- SQL注入回顾篇(四)
- cmd sqlplus远程连接_sqlplus连接远程数据库
- Nodejs生成二维码图片文件
- 服务器装exi系统_ESXI 6.5安装详细步骤
- 错误类型:reflection.ReflectionException: Could not set property ‘xxx‘ of ‘class ‘xxx‘ with value ‘xxx‘
- Mac 退出与卸载 GlobalProtect