win8win8win7双系统光盘版怎么把光盘里的东西拷到U盘里

Android(58)
&&&&& 在Android开发过程中,经常要在Activity之间传递参数,使用Android系统提供的方法可以传递基本数据类型的变量,但有时候我们经常要传递一些复杂的数据类型或自定义的类,这种情况的参数无法直接传递,我们可以通过序列化实现。本文来学习Android中的序列化
内容参考:/renqingping/archive//Parcelable.html
1.为什么要序列化?
1)永久性保存对象,保存对象的字节序列到本地文件中;
2)通过序列化对象在网络中传递对象;
3)通过序列化在进程间传递对象。
2.实现序列化的方法
Android 中实现序列化有两个选择:
一是实现Serializable接口(是JavaSE本身就支持的),
一是实现Parcelable接口(是Android特 有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))。
实现Serializable接 口非常简单,声明一下就可以了,而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。
注:Android 中Intent传递对象有两种方法:一是Bundle.putSerializable(Key,Object),另一种是 Bundle.putParcelable(Key,Object)。当然这些Object是有一定的条件的,前者是实现了Serializable接 口,而后者是实现了Parcelable接口。
3.选择序列化方法的原则
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
5.应用场景
需要在多个部件(Activity或Service)之间通过Intent传递一些数据,简单类型(如:数字、字符串)的可以直接放入Intent。复杂类型必须实现Parcelable接口。
6.具体实现
(1)Serializable接口:
将需要序列化的类实现implements&Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化。
(2)Parcelable接口:
不仅需要implements &Parcelabel,还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator 接口。
public class ListInfo implements Parcelable {
String name;
String time;
int image;
public ListInfo() {
public ListInfo(String name, String time, int image) {
this.name = name;
this.time = time;
this.image = image;
public String getName() {
return name;
public void setName(String name) {
this.name = name;
public String getTime() {
return time;
public void setTime(String time) {
this.time = time;
public int getImage() {
return image;
public void setImage(int image) {
this.image = image;
* 写入序列化,按顺序写入
public void writeToParcel(Parcel parcel, int arg1) {
parcel.writeString(name);
parcel.writeString(time);
parcel.writeInt(image);
public static final Creator&ListInfo& CREATOR = new Creator&ListInfo&() {
* 从序列化通道中传出来
public ListInfo createFromParcel(Parcel parce) {
//读取内容,加到info里面,相当于new一个info对象,所以直接写在构造器里面
// String name=parce.readString();
// String time=parce.readString();
// int image=parce.readInt();
// ListInfo info=new ListInfo();
// info.setName(name);
// info.setTime(time);
// info.setImage(image);
return new ListInfo(parce);
//序列化数组
public ListInfo[] newArray(int arg0) {
//有参构造器
public ListInfo(Parcel parce) {
name = parce.readString();
time = parce.readString();
image = parce.readInt();
public int describeContents() {
AndroidStudio里面有插件可以自动实现Parcelable
先安装插件
点击安装,之后重启就可以用了。
用的时候:
在对象上按快捷键alt+insert,弹出下图:
然后选择Parcelable,之后代码会自动的更改好的。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:38990次
排名:千里之外
原创:50篇
转载:38篇
(1)(2)(2)(2)(3)(1)(4)(6)(17)(1)(16)(12)(12)(5)浅谈序列化的两种接口-Serializable和Parcelable - 简书
浅谈序列化的两种接口-Serializable和Parcelable
一、序列化在java中,序列化是指将对象转化为字节序列的过程。而反序列化则是将字节序列转为对象。换句话说,序列化就是将对象进行流化。序列化的作用:
永久性保存对象,保存对象的字节序列到本地文件中;
通过序列化对象在网络中传递对象;
通过序列化在进程间传递对象。
通过序列化在intent中传递自定义对象。
二、如何使用Serializable接口Serializable是一个空接口,使用起来相当简单,只要在所需序列化的类实现这个接口就可以了,系统会帮你实现对象的序列化。我们举个简单的例子
public class Person implements Serializable{
public static final long serialVersionUID = 1L;
通过IO流可轻松进行序列化和反序列化。
//序列化过程
Person person = new Person("Tim",25,"male");
ObjectOutputStream output
= new ObjectOutputStream(new FileOutputStream("Tim.txt"));
output.writeObject(person);
output.close();
//反序列化过程
ObjectInputStream input
= new ObjectInputStream(new FileInputStream("Tim.txt"));
Person person = (Person)input.readObject();
input.close();
如果有多个对象写入同一个文件,为了正确读取数据,完成反序列化,必须保证向对象输出流写对象的顺序与从对象输入流中读对象的顺序一致。值得注意的是,虽然通过反序列化恢复得到了对象,但是和序列化前的对象并非同一对象。有细心的同学发现了我们在类的声明中加上了一行
private static final long serialVersionUID = 1L;
这句话有什么用呢?其实这句话并非必须的,没有这句话也可以序列化。只是这句话会对反序列造成一定的影响。序列化的时候系统会将serialVersonUID一同写入序列化的文件,当反序列的时候系统会检测文件中的serialVersonUID,只有和当前类的serialVersonUID值一致时,反序列化才能成功,否则程序会crash.serialVersionUID的赋值有两种方式,一种是默认值,比如上面的1L;另一种是根据当前类的结构生成hash值。无论是哪种方式都可以,只要我们显示定义UID,就可以反序列化成功。如果没有显示定义UID,系统自动产生一个hash值,当序列化后,如果类的结构发生变化,比如增加了某个成员变量,那么UID的值也会改变,这时当前类的UID和序列化文件中的UID就不一致了,程序就会报错。所以建议手动给UID赋值。但有一种特例,即使前后UID一致,反序列化也会失败,即类发生了特殊的改变,比如修改类名,改变成员变量的类型。
有时候我们并不想让所以成员变量进行序列化,这时我们只要在变量声明前加上transient关键字,就可将其排除在外.
private transient S
还有一点要注意,静态成员不属于对象,所以不参与序列化。
二、Parcelable接口
android为我们提供了新的序列化方式,即parcelable接口。parcelable使用起来比较麻烦,但是相对于serializable效率比较高。为什么这样说呢?因为serializable使用了大量的IO流操作。parcelable是android上的序列化方式,比较适合用在android开发上。接下来我们看看如何使用Parcelable接口
public class Person implements Parcelable{
private static final long serialVersionUID = 1L;
public Person(String name,int age,String sex){
this.name =
this.age =
this.sex =
public int describeContents(){
return 0 ;
public void writeToParcel(Parcel out,int flags){
out.writeString(name);
out.writeInt(age);
out.writeString(sex);
public static final Parcelable.Creator&Person& CREATOR = new Parcelable.Creator&Person&(){
public Person createFromParcel(Parcel in){
return new Person(in);
public Person[] newArray(int size){
return new Person[size];
private Person(parcel in){
name = in.readString();
age = in.readInt();
sex = in.readString();
这是典型的Parcelable序列化的写法,从上面代码看出,writeToParcel方法实现了序列化,Parcel保存了序列化的数据。反序列化由CREATOR完成,read方法读取parcel内的数据,完成反序列化。describeContents方法用于描述当前对象内容,如果含有文件描述符,返回1,大部分情况下都返回0;writeToParcel的flags参数取值为0或1;1表示不能立刻释放资源,大部分情况下取0;
补充:Serializable和Parcelable不仅可以使用在进程间通信,还可以用于Intent的数据传输。方法很简单,
intent.putExtra(key,object);
object传入一个序列化对象。获取数据时,如果是Serializable对象,使用
getIntent().getSerializableExtra(key);
如果是Parcelable对象,使用
getIntent().getParcelableExtra(key).
好了,我所知道的Serializable和Parcelable知识基本就讲完了。这是我第一次在简书上写文章,如果有什么写得不好的地方,欢迎指正。Android中两种序列化方式的比较Serializable和Parcelable - 博客频道 - CSDN.NET
分类:Andoid
Serializable和Parcelable接口可以完成对象的序列化过程,当我们需要通过Intent和Binder传输数据时就需要使用者两种序列化方式。还有,我们需要对象持久化到存储设备或者通过网络传输给其他客户端,这个使用也需要使用Serializale来完成对象的序列化。在Android应用开发中,这两种方式都很常见,但两者方式并不相同。
1.Serializable接口
Serializable接口是Java提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用Serializable来实现的对象的序列化相当简单,只需要在类的生命中指定一个类似相面的标识即可自动实现默认的序列化过程。
private static final long serialVersionUID=;
完整的对象序列化代码示例如下:
public class User implements Serializable{
private static final long serialVersionUID=;
public int userId;
public String userN
User user=new User(0,"wcl_","123456");
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("user.obj"));
out.writeObject(user);
ObjectInputStream in=new ObjectInputStream(new FileInputStream("user.obj"));
User user=(User)in.readObject();
in.close();
这种方式是Java提供的一种序列化方式,过程非常简单,甚至有些开发人员都不需要声明serialVersionUID也可以完成这个过程,但serialVersionUID到底需不需要指定呢?
Java API既然提供了这个serialVersionUID,那么它必定是有用的。这个serialVersionUID是用来辅助序列化和反序列化过程的,原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常地被反序列化。
serialVersionUID的详细工作过程是这样的:序列化的时候系统会把当前类的serialVersionUID写入序列化的二进制文件中,当反序列化的时候系统会检测文件中的serialVersionUID是否和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化;否则说明当前类和反序列化的类相比发生了某些变化,比如成员变量的数量、类型发生了变化,这个时候是无法正常反序列化的。
一般来说,我们应该手动指定serialVersionUID的值,比如1L,也可以让IDE根据当前类的结构自动去生成它的hash值,这样序列化和反序列化时两者的serialVersionUID是相同的,因此可以正常进行反序列化操作。如果不手动指定serialVersionUID的值反序列化时当前类有些改变,比如增加或者删除了某些成员变量,那么系统就会重新计算当前类的hash值并把它赋值给serialVersionUID,这个时候当前类的serialVersionUID就和反序列化数据中的serialVersionUID不一致,就会造成反序列化失败的结果。所以,手动指定serialVersionUID可以在很大程度上避免反序列化过程的失败。比如当版本升级后,我们可能删除了某个成员变量也可能增加了一些新的成员变量,这个时候我们的反序列化过程依然能够成功,程序仍然能够最大限度地回复数据;相反,如果不指定serialVersionUID的话,程序会发生Crash。
当然,我们还需要考虑一种情况,如果类结构发生了非城规改变,比如修改了类名,修改了成员变量的类型,这个时候尽管serialVersionUID验证通过了,但是反序列化过程仍然会失败,因为类的结构有了毁灭性的改变,根本无法从老版本的数据中还原出一个新的类结构的对象。
对于使用序列化还有两点需要注意:
1.静态成员变量属于类不属于对象,所以不参与序列化过程
2.用transient关键字标记的成员变量不参与序列化过程
2.Parcelable接口
Parcelable接口是Android SDK提供的一种专门用于Android应用中对象的序列化和反序列化的方式,相比于Seriablizable具有更好的性能。实现Parcelable接口的对象就可以实现序列化并可以通过Intent和Binder传递。
下面是一个完成的实现了Parcelable接口的类
public class User implements Parcelable{
public int userId;
public String userN
public User(int userId,String userName,String password,Book book){
this.userId=userId;
this.userName=userN
this.password=
this.book=
public int describeContents(){
public void writeToParcel(Parcel out,int flags){
out.writeInt(userId);
out.writeString(userName);
out.writeString(password);
out.writeParcelable(book,0);
public static final Parcelable.Creator&User& CREATOR=new Parcelable.Creator&User&(){
public User createFromParcel(Parcel in){
return new User(in);
public User[] newArray(int size){
return new User[size];
private User(Parcel in){
userId=in.readInt();
userName=in.readString();
password=in.readString();
book=in.readParcelable(Thread.currentThread().getContextClassLoader());
看起来比Serializable方式复杂太多。我们使用表格把Parcelable方式的相关方法进行说明
createFromParcel(Parcel in)
从序列化后的对象中创建原始对象
newArray(int size)
创建指定长度的原始对象数组
User(Parcel in)
从序列化后的对象中创建原始对象
writeToParcel(Parcel out,int flags)
将当前对象写入序列化结构中
PARCALABLE_WRITE_RETURN_VALUE
describeContents
返回当前对象的内容描述,几乎所有情况都返回0,仅在当前对象中存在文件描述符时返回1
CONTENTS_FILE_DESCRIPTOR
既然Parcelable和Serializable都可以实现序列化并且可以用于Intent间的数据传递,那么两者有什么区别呢?
Serializable
Parcelable
Android SDK API
序列化和反序列化过程需要大量的I/O操作
序列化和反序列化过程不需要大量的I/O操作
序列化到本地或者通过网络传输
内存序列化
wangchunlei123
排名:千里之外
(15)(4)(6)(1)android对象序列化Parcelable浅析
来源:博客园
一、android序列化简介
我们已经知道在Android使用Intent/Bindler进行IPC传输数据时,需要将对象进行序列化。
JAVA原本已经提供了Serializable接口来实现序列化,使用起来非常简单,主要用于对象持久化以及对象的网络传输。Serializable开销比较大,因为序列化和反序列化的过程需要大量的I/O操作。
Android提供了Parcelable对象序列化操作是内存序列化,主要用于Intent/Bindler的IPC数据传输。
 
二、Parcelable序列化使用方法
比如我们使用Parcelable在两个activity直接通过intent进行传输一个Book的对象。

 1 package org.xerrard.demo2;
 2 
 3 import android.os.P
 4 import android.os.P
 5 
 6 /**
 7
* Created by xuqiang on 16-1-20.
 8
*/
 9 public class Book implements Parcelable{
10 
11
public S
12 
13
public Book(String bookname){
14
this.bookname =
15
}
16 
17
protected Book(Parcel in) {
18
bookname = in.readString();
19
}
20 
21
public static final Creator&Book& CREATOR = new Creator&Book&() {
22
@Override
23
public Book createFromParcel(Parcel in) {
24
return new Book(in);
25
}
26 
27
@Override
28
public Book[] newArray(int size) {
29
return new Book[size];
30
};
32 
33
@Override
34
public int describeContents() {
35
return 0;
36
}
37 
38
@Override
39
public void writeToParcel(Parcel dest, int flags) {
40
dest.writeInt(bookname);
41
}
42 }

我们需要完成以下几部。
1. 实现Parcelable接口 2. 添加实体属性 3. 覆写writeToParcel(Parcel dest, int flags)方法,指定写入Parcel类的数据。 4. 创建Parcelable.Creator静态对象,有两个方法createFromParcel(Parcel in)与newArray(int size),前者指定如何从Parcel中读取出数据对象,后者创建一个数组。 5. 覆写describeContents方法,默认返回0。 
 
然后我们就可以使用Intent中的putExtra方法将Book对象写入Intent中,然后使用getExtra方法,就可以从Intent中读出Book对象。
 
三、Parcelable底层序列化原理
从上面的例子可以看到,Parcelable的序列化方式使用起来还是比较麻烦的。但是,这种方式效率上是比较好的,因为Parcelable的序列化过程是再底层native通过内存操作实现的。
详细的JNI和C/C++底层的内存操作可以看这篇文章
摘抄里面最重要的一句结论
整个读写全是在内存中进行,主要是通过malloc()、realloc()、memcpy()等内存操作进行,所以效率比JAVA序列化中使用外部存储器会高很多
因此,在IPC过程中,android推荐使用Parcelable序列化方式
 
四:Parcelable的调用关系
我们知道如果要使用Parcelable,必须按照要求实现这五项操作
1. 实现Parcelable接口 2. 添加实体属性 3. 覆写writeToParcel(Parcel dest, int flags)方法,指定写入Parcel类的数据。 4. 创建Parcelable.Creator静态对象,有两个方法createFromParcel(Parcel in)与newArray(int size),前者指定如何从Parcel中读取出数据对象,后者创建一个数组。 5. 覆写describeContents方法,默认返回0。 
 这里面又是怎样的调用关系呢?

我们看到,writeToParcel是在startActivity的过程中由intent-&Bundle-&Parcel 一步一步的调用的,然后WriteToParcel会调用native方法,在底层做序列化操作

而createFromParcel是在收到Intent之后,由Intent-&Bundle-&Parcel 一步一步的调用。
由此可以看出,Parcel的填包解包都是离不开Bundle的。
这里其实还是有一个疑问,这个Creator是怎么一回事呢?
我们从源码中截取Creator这部分来看看。

 1
public final &T extends Parcelable& T readParcelable(ClassLoader loader) {
 2
Parcelable.Creator&T& creator = readParcelableCreator(loader);
 3
if (creator == null) {
 4
return null;
 5
if (creator instanceof Parcelable.ClassLoaderCreator&?&) {
 7
return ((Parcelable.ClassLoaderCreator&T&)creator).createFromParcel(this, loader);
 8
return creator.createFromParcel(this);
10
}
11 
12
/** @hide */
13
public final &T extends Parcelable& T readCreator(Parcelable.Creator&T& creator,
14
ClassLoader loader) {
15
if (creator instanceof Parcelable.ClassLoaderCreator&?&) {
16
return ((Parcelable.ClassLoaderCreator&T&)creator).createFromParcel(this, loader);
17
return creator.createFromParcel(this);
19
}
20 
21
/** @hide */
22
public final &T extends Parcelable& Parcelable.Creator&T& readParcelableCreator(
23
ClassLoader loader) {
24
String name = readString(); //此处获得类名,还不太清楚如何获得的,如果想深入学习可以再研究
25
if (name == null) {
26
return null;
27
Parcelable.Creator&T&
29
synchronized (mCreators) {
30
HashMap&String,Parcelable.Creator& map = mCreators.get(loader);
31
if (map == null) {
32
map = new HashMap&String,Parcelable.Creator&();
33
mCreators.put(loader, map);
34
creator = map.get(name);
36
if (creator == null) {
37
try {
38
Class c = loader == null ?
39
Class.forName(name) : Class.forName(name, true, loader);
40
Field f = c.getField("CREATOR");
41
creator = (Parcelable.Creator)f.get(null);
42
catch (IllegalAccessException e) {
44
Log.e(TAG, "Illegal access when unmarshalling: "
45
+ name, e);
46
throw new BadParcelableException(
47
"IllegalAccessException when unmarshalling: " + name);
48
catch (ClassNotFoundException e) {
50
Log.e(TAG, "Class not found when unmarshalling: "
51
+ name, e);
52
throw new BadParcelableException(
53
"ClassNotFoundException when unmarshalling: " + name);
54
catch (ClassCastException e) {
56
throw new BadParcelableException("Parcelable protocol requires a "
57
+ "Parcelable.Creator object called "
58
+ " CREATOR on class " + name);
59
catch (NoSuchFieldException e) {
61
throw new BadParcelableException("Parcelable protocol requires a "
62
+ "Parcelable.Creator object called "
63
+ " CREATOR on class " + name);
64
catch (NullPointerException e) {
66
throw new BadParcelableException("Parcelable protocol requires "
67
+ "the CREATOR object to be static on class " + name);
68
if (creator == null) {
70
throw new BadParcelableException("Parcelable protocol requires a "
71
+ "Parcelable.Creator object called "
72
+ " CREATOR on class " + name);
73
}
74 
75
map.put(name, creator);
76
}
78 
79
return
80
}

重点看粗体部分的代码——真想大白:
在接收端收到parcel之后,解析的时候,会通过反射去获取对象的Creator,然后保存到一个hashmap中。然后调用Creator的createFromParcel方法来实现解包。
 
反射在源码中也是无处不在!
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动

我要回帖

更多关于 光盘安装win8系统步骤 的文章

 

随机推荐