在开发Android的时候,我们有时候需要用到数据的持久化存储,或者在进程间传递数据。其中,可能需要对对象进行序列化,序列化后的对象可以通过Intent或者Boundle进行传输。接下来,我想再介绍一些。一、什么是序列化,什么是反序列化序列化:将数据结构或对象转换为二进制字符串的过程。反序列化:将序列化过程中产生的二进制字符串转换成数据结构或对象的过程。简单来说,序列化就是将我们生成的对象(比如在磁盘上)存储起来,以备将来使用或者在网络上传输,而反序列化就是将我们之前序列化生成的二进制字符串重新生成一个对象的过程。注意这里我们反复提到的序列化和反序列化都是针对对象的,不是针对类的。因为我们访问和传递的是对象,而不是类,当我们需要重新获取之前的对象时,我们直接读取(从文件或网络),而不是根据类new创建对象,这一点需要注意。2.序列化后的单词序列化有两种方式,一种是实现Serializable接口,一种是实现Parceable接口。下面将详细介绍这两种方法。A。实现Serializable接口这个序列化方法是Java提供的。它的优点是简单。其实Serializable接口是一个空接口,所以我们不需要实现任何抽象方法,但是我们往往需要在类Identifier(serialVersionUID)中声明一个静态变量,但这并不是必须的。如果我们不声明,仍然可以实现序列化,但是这会对反序列化产生一定的影响,可能会导致我们修改类后反序列化对象失败。声明方式如下:privatestaticfinallongserialVersionUID=8711368828010083044L;注意这里的值可以是任意值。让我们详细地实现它。packagecom.qc.admin.myserializableparceabledemo;importjava.io.Serializable;/***Createdbyadminon2016/12/1.*/publicclassUserimplementsSerializable{privatestaticfinallongserialVersionUID=519067123721295773L;publicintuserId;publicStringuserName;publicbooleanisMale;publicUser(intuser,d,StringuserName){intuser,d,StringuserI=userId;this.userName=userName;this.isMale=isMale;}@OverridepublicStringtoString(){return"User{"+"userId="+userId+",userName="+userName+",isMale="+isMale+"}";}}下面是序列化和反序列化过程:txt")));out.writeObject(user);out.close();//反序列化//注意这里后面的“/myfile.txt”前面有斜杠“/”,否则会报“FileNotFoundException”异常ObjectInputStreamin=newObjectInputStream(newFileInputStream(getFilesDir()+"/myfile.txt"));UsermUser=(User)in.readObject();textView.setText(mUser.toString());in.close();Log.i("test",mUser.toString());}运行结果截图:注意:如果在Android项目中调用上述方法,不要忘记在Manifest.xml文件中配置如下权限:b。Parceable接口的实现方法由Android提供。与前面的方法相比,这个方法稍微复杂一些。我们需要自己享受序列化和反序列化操作,但是效率更高,不需要进行大量的I/O操作,而且这种方式也是Android推荐的序列化方式,所以我们应该安装Parceable。只要实现了这个接口,就可以序列化一个类的对象,通过Intent和Binder传递。请参见下面的示例:){returnnewBook(in);}@OverridepublicBook[]newArray(intsize){returnnewBook[size];}};@OverridepublicintdescribeContents(){return0;}@OverridepublicvoidwriteToParcel(Parcelparcel,inti){parcel.writeString(bookTitle);包裹。writeInt(bookId);}}在这里,Book类实现了Parcelable接口。其实在AndroidStudioIDE中,上述过程非常简单。我们只需要定义一个类,实现Parcelable接口,然后定义我们的属性或者说是一个字段即可。根据提示的错误,按照它提示的方法覆盖对应的方法即可。之后的东西其实都可以自动生成(但是如果需要构造方法,就需要自动生成,toString()方法也是自己实现的),所以不用担心实现起来很麻烦Android开发中Parceable接口,因为AS会自动帮你生成。上面我们已经完整的实现了Book类的Parceable接口,那么接下来怎么序列化和反序列化呢?如果你说,你刚才不是已经说了吗,读取文件的方式马上就准备好了……当你这样做的时候,你会发现会报如下错误:Why???...What是什么情况?提示Book类没有实现序列化:/System.err:java.io.NotSerializableException:com.qc。admin.myserializableparceabledemo.Book嗯,出现这种问题的原因不是我们的实现过程有问题,而是这个类的使用方式不行。至此,我们明白Serializable和Parceable还是有区别的。刚才我们说了,Parceable效率更高,没有像Serializable那样大量的I/O操作。这句话的具体意思就是Serializable和Parcelable的区别揭示了:虽然两者都是用来支持序列化和反序列化操作的,但是两者最大的区别在于存储介质不同。Serializable将序列化的对象存储在硬盘上。一般来说,I/O是用来读写的,Parcelable是存放在内存中的,就是内存读写的。熟悉计算机组成原理的朋友都知道,内存的读写速度显然要比I/O快很多。读写速度快,这也是Android中推荐使用Parcelable来序列化对象的原因。那么我们应该如何使用通过实现Parcelable接口序列化的对象呢?答案是:通过Intent,除了基本类型,Intent只能传递序列化的对象。对应这两个序列化方法,有两个对应的方法:mIntent.getSerializableExtra(stringname);mIntent.getParcelableExtra(字符串名称);当然放入的操作没有这个区别,都是方法:mIntent.putExtra();我们可以在第一个Activity中将序列化后的对象放入Intent中,在另一个Activity中取出,例如:获取另一端的对象,例如:BundlemBundle=getIntent().getExtras();BookmBook=mBundle.getParcelable("book1");我们再看类User实现Parceable接口的过程,里面包含了一个可序列化的类Book,具体细节和上面有点区别:packagecom.qc.admin.myserializableparceabledemo;importandroid.os.Parcel;importandroid.os.Parcelable;/***Createdbyadminon2016/12/1.*/publicclassUserimplementsParcelable{publicintuserId;publicStringuserName;publicbooleanisMale;publicBookbook;publicUser(intuserId,StringuserName,booleanisMale,Bookbook){this.userId=userId;this.userName=userName;this.isMale=isMale;这个。book=book;}protectedUser(Parcelin){userId=in.readInt();userName=in.readString();isMale=in.readByte()!=0;//这是区别1//也可以通过这种方式:book=in.readParcelable(Thread.currentThread().getContextClassLoader());book=in.readParcelable(Book.class.getClassLoader());}publicstaticfinalCreatorCREATOR=newCreator(){@OverridepublicUsercreateFromParcel(Parcelin){returnnewUser(in);}@OverridepublicUser[]newArray(intsize){returnnewUser[size];}};//几乎所有情况下都应该返回0,只有当前对象中有文件描述时,该方法返回CONTENTS_FILE_DESCRIPTOR(常量值为1)@OverridepublicintdescribeContents(){return0;}//将对象写入序列化结构中,其中i标志有两个值,0或1(PARCELABLE_WRITE_RETURN_VALUE)//为1时表示当前对象需要被作为返回值返回,不能立即返回释放资源,几乎都是0@OverridepublicvoidwriteToParcel(Parcelparcel,inti){parcel.writeInt(userId);parcel.writeString(userName);//这里注意,不是直接写boolean值,但写入整数值parcel.writeByte((byte)(isMale?1:0));//This是差值2parcel.writeParcelable(book,i);}@OverridepublicStringtoString(){return"User{"+"userId="+userId+",userName="+userName+",isMale="+isMale+"book="+book.toString()+"}";}}可以看出已经正确打印了结果:注意:在Parcelable中,我们不能直接写boolean值,而是转换成整数值存储,这里是Byte,当然你也可以用Int等。