android开发之Parcelable使用详解

时间:2022-02-21 17:32:06

想要在两个activity之间传递对象,那么这个对象必须序列化,android中序列化一个对象有两种方式,一种是实现Serializable接口,这个非常简单,只需要声明一下就可以了,不痛不痒。但是android中还有一种特有的序列化方法,那就是实现Parcelable接口,使用这种方式来序列化的效率要高于实现Serializable接口。不过Serializable接口实在是太方便了,因此在某些情况下实现这个接口还是非常不错的选择。

使用Parcelable步骤:

1.实现Parcelable接口

2.实现接口中的两个方法

public int describeContents();
public void writeToParcel(Parcel dest, int flags);

第一个方法是内容接口描述,默认返回0就可以了

第二个方法是将我们的对象序列化一个Parcel对象,也就是将我们的对象存入Parcel中

3.实例化静态内部对象CREATOR实现接口Parcelable.Creator,实例化CREATOR时要实现其中的两个方法,其中createFromParcel的功能就是从Parcel中读取我们的对象。

也就是说我们先利用writeToParcel方法写入对象,再利用createFromParcel方法读取对象,因此这两个方法中的读写顺序必须一致,否则会出现数据紊乱,一会我会举例子。

看一个代码示例:

public class Person implements Parcelable{

    private String username;
private String nickname;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String username, String nickname, int age) {
super();
this.username = username;
this.nickname = nickname;
this.age = age;
}
public Person() {
super();
}
/**
* 这里的读的顺序必须与writeToParcel(Parcel dest, int flags)方法中
* 写的顺序一致,否则数据会有差错,比如你的读取顺序如果是:
* nickname = source.readString();
* username=source.readString();
* age = source.readInt();
* 即调换了username和nickname的读取顺序,那么你会发现你拿到的username是nickname的数据,
* 而你拿到的nickname是username的数据
* @param source
*/
public Person(Parcel source) {
username = source.readString();
nickname=source.readString();
age = source.readInt();
}
/**
* 这里默认返回0即可
*/
@Override
public int describeContents() {
return 0;
}
/**
* 把值写入Parcel中
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(username);
dest.writeString(nickname);
dest.writeInt(age);
} public static final Creator<Person> CREATOR = new Creator<Person>() { /**
* 供外部类反序列化本类数组使用
*/
@Override
public Person[] newArray(int size) {
return new Person[size];
} /**
* 从Parcel中读取数据
*/
@Override
public Person createFromParcel(Parcel source) {
return new Person(source);
}
};
}

本工程源码http://pan.baidu.com/s/1hqzY3go

最后贴上Parcelable源码,Google已经给了一个示例了:

/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package android.os; /**
* Interface for classes whose instances can be written to
* and restored from a {@link Parcel}. Classes implementing the Parcelable
* interface must also have a static field called <code>CREATOR</code>, which
* is an object implementing the {@link Parcelable.Creator Parcelable.Creator}
* interface.
*
* <p>A typical implementation of Parcelable is:</p>
*
* <pre>
* public class MyParcelable implements Parcelable {
* private int mData;
*
* public int describeContents() {
* return 0;
* }
*
* public void writeToParcel(Parcel out, int flags) {
* out.writeInt(mData);
* }
*
* public static final Parcelable.Creator&lt;MyParcelable&gt; CREATOR
* = new Parcelable.Creator&lt;MyParcelable&gt;() {
* public MyParcelable createFromParcel(Parcel in) {
* return new MyParcelable(in);
* }
*
* public MyParcelable[] newArray(int size) {
* return new MyParcelable[size];
* }
* };
*
* private MyParcelable(Parcel in) {
* mData = in.readInt();
* }
* }</pre>
*/
public interface Parcelable {
/**
* Flag for use with {@link #writeToParcel}: the object being written
* is a return value, that is the result of a function such as
* "<code>Parcelable someFunction()</code>",
* "<code>void someFunction(out Parcelable)</code>", or
* "<code>void someFunction(inout Parcelable)</code>". Some implementations
* may want to release resources at this point.
*/
public static final int PARCELABLE_WRITE_RETURN_VALUE = 0x0001; /**
* Bit masks for use with {@link #describeContents}: each bit represents a
* kind of object considered to have potential special significance when
* marshalled.
*/
public static final int CONTENTS_FILE_DESCRIPTOR = 0x0001; /**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return a bitmask indicating the set of special object types marshalled
* by the Parcelable.
*/
public int describeContents(); /**
* Flatten this object in to a Parcel.
*
* @param dest The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written.
* May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
public void writeToParcel(Parcel dest, int flags); /**
* Interface that must be implemented and provided as a public CREATOR
* field that generates instances of your Parcelable class from a Parcel.
*/
public interface Creator<T> {
/**
* Create a new instance of the Parcelable class, instantiating it
* from the given Parcel whose data had previously been written by
* {@link Parcelable#writeToParcel Parcelable.writeToParcel()}.
*
* @param source The Parcel to read the object's data from.
* @return Returns a new instance of the Parcelable class.
*/
public T createFromParcel(Parcel source); /**
* Create a new array of the Parcelable class.
*
* @param size Size of the array.
* @return Returns an array of the Parcelable class, with every entry
* initialized to null.
*/
public T[] newArray(int size);
} /**
* Specialization of {@link Creator} that allows you to receive the
* ClassLoader the object is being created in.
*/
public interface ClassLoaderCreator<T> extends Creator<T> {
/**
* Create a new instance of the Parcelable class, instantiating it
* from the given Parcel whose data had previously been written by
* {@link Parcelable#writeToParcel Parcelable.writeToParcel()} and
* using the given ClassLoader.
*
* @param source The Parcel to read the object's data from.
* @param loader The ClassLoader that this object is being created in.
* @return Returns a new instance of the Parcelable class.
*/
public T createFromParcel(Parcel source, ClassLoader loader);
}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。若有错误地方,还望批评指正,不胜感激。