今天,简单讲讲android如何使用Parcelable接口传递数据。

这个其实也很简单,之前我写过博客将关于Serializable接口传递对象,实现Parcelable接口也是为了传递对象,但效率更高,所以在网上查找了相关的资料,这里记录一下。

 

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

 

1.实现序列化的方法

Android中实现序列化有两个选择:一是实现Serializable接口(是JavaSE本身就支持的),一是实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))。实现Serializable接口非常简单,声明一下就可以了,而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。

注:Android中Intent传递对象有两种方法:一是Bundle.putSerializable(Key,Object),另一种是Bundle.putParcelable(Key,Object)。当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口。

 

2.选择序列化方法的原则

1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。

2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。


2.使用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 CREATOR = new Creator() {        /**         * 供外部类反序列化本类数组使用         */        @Override        public Person[] newArray(int size) {            return new Person[size];        }        /**         * 从Parcel中读取数据         */        @Override        public Person createFromParcel(Parcel source) {            return new Person(source);        }    };}

简单讲讲,其实实现Parcelable接口就是对对象序列化,使对象可以在Intent或进程之间传递。使用也很简单,首先写一个类,实现Parcelable接口,对每个变量设置get和set函数,然后重写public int describeContents();,这个固定返回0就可以。还需要重写public void writeToParcel(Parcel dest, int flags);这里面通过dest.writeString(username);将变量一个一个的序列化,然后在构造函数里写一个获取序列化数据的函数,参数为Parcel,比如public Person(Parcel source),通过source.readString()来一个一个的读取变量。这里需要注意一点,读取变量的顺序必须和之前写入变量的顺序保持一致,不然会出错。最后还需要实例化静态内部对象CREATOR实现接口Parcelable.Creator,实例化CREATOR时要实现其中的两个方法,其中createFromParcel的功能就是从Parcel中读取我们的对象。public Person createFromParcel(Parcel source)和public Person[] newArray(int size)都是调用new Person(source)来读取序列化变量的,只是createFromParcel是读取一个对象,newArray是读取一个数组。

 

这里还需要注意一点,Parcelable只能对内存对象序列化,不能对需要存储在文件或SD等设备进行序列化,如果需要将对象序列化存储到文件,实现Serializable接口就可以了。

最后贴上Parcelable源码:

/* * 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 CREATOR, which * is an object implementing the {@link Parcelable.Creator Parcelable.Creator} * interface. *  * 

A typical implementation of Parcelable is:

* *
 * 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<MyParcelable> CREATOR *             = new Parcelable.Creator<MyParcelable>() { *         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(); *     } * }
*/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 * "Parcelable someFunction()", * "void someFunction(out Parcelable)", or * "void someFunction(inout Parcelable)". 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 { /** * 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 extends Creator { /** * 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); }}

 

android 如何使用Parcelable接口就讲完了。

 

就这么简单。

更多相关文章

  1. Android中几种图像特效处理方法小结
  2. Android Asynchronous Http Client-Android异步网络请求客户端接
  3. Android 4.2 webview注入js对象时需要注意的问题
  4. android基础学习--->Android SharedPreferences存储对象和图片(An
  5. Android LayoutInflater inflate方法效率
  6. 下载Android Sdk源码方法

随机推荐

  1. Android(安卓)SDK4.0离线快速安装方法
  2. Android(安卓)AOSP基础(五)Android(安卓)St
  3. android
  4. tools:context=".MainActivity的作用
  5. Android(安卓)AOSP基础(四)Source Insight
  6. convertview机制
  7. Android(安卓)AOSP基础(四)Source Insight
  8. 【1510-14】大规模登陆界面
  9. Android(安卓)的设计模式---责任链模式
  10. android 写入收件箱