Android开发系列之对象序列化

转自博客:http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html

 

1、实现序列化的作用

      数据的传递在应用中是必要的,然而普通的数据传递只是支持基本数据类型,如String, int ,或者更高些的数据类型,如arraylist,Object等。但是开发中,我们往往需要传递对象,来达到便利的数据传输目的,这就需要实现对象的序列化。

       数据的传递包括本地数据存取,网络数据传输,以及Intent数据传输等。

 

2、实现序列化的方法

    1) Parcelable

    2)Serializable

 

3、序列化使用原则

    1) 使用内存时,Parcelable效率要高于Serializable,所以推荐使用Parcelable。

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

    3) Parcelable不能使用在将数据保存在磁盘上,因此此时建议使用Serializable。

 

 

4、Serializable

      Serializable的实现,只需要 implements Serializable即可,系统会自动将其序列化 

 

 

5、Parcelable

      1) implements  Parcelable

      2) 重写describeContents、writeToParcel两个方法,writeToParcel用于将当前对象映射为Parcel对象

          @Override

        public int describeContents() {

            // 内容描述接口,默认返回0即可

            return 0;

         }

 

 @Override

 public void writeToParcel(Parcel dest, int flags) {

     // 将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中

     dest.writeString(id);

     dest.writeString(path);

     dest.writeString(thumbnailPath);

     bitmap.writeToParcel(dest, 0);

     }

    

       3)创建Parcelable.Creator对象,并重写createFromParcel、newArray方法;createFromParcel用于将Parcel对象映射为你的对象

             public static final Parcelable.Creator<ImageItem> CREATOR = new Parcelable.Creator<ImageItem>() {

 

    @Override

     public ImageItem createFromParcel(Parcel source) {

         ImageItem item = new ImageItem();

         item.id = source.readString();

         item.path = source.readString();

         item.thumbnailPath = source.readString();

         item.bitmap = Bitmap.CREATOR.createFromParcel(source);

         return item;

      }

 

      @Override

      public ImageItem[] newArray(int size) {

           return new ImageItem[size];

      }

          };

            

   所以Parcelable的用法可以总结为implements Parcelable接口,然后加上将你的对象封装为Parcel对象的writeToParcel方法,附带描述的describeContents;然后加上将Parcel对象映射为你的对象的Parcel.Creator对象,并重写映射方法即可。

 

 注意事项:

 

 1)writeToParcel与createFromParcel两个方法添加与取出变量的顺序要一致

 2)Bitmap对象的操作,要采用 bitmap.writeToParcel(dest, 0) 与 Bitmap.CREATOR.createFromParcel(source)

 3)Parcel.Creator的创建保持不变 public static final Parcelable.Creator<ImageItem> CREATOR = new Parcelable.Creator<ImageItem>() ,最好只替换<T>部分

 4)Bitmap的传递,大小限制为40KB

 5)Parcel对List的读写:dest.writeList(photoItems) 与 source.readList(this.photoItems, ImageItem.class.getClassLoader())。代码如下:

       

       public List<ImageItem> photoItems = new ArrayList<ImageItem>();

         //Parcel读取构造

        public ImageFolder (Parcel source){

             source.readList(this.photoItems, ImageItem.class.getClassLoader());

        }

 

       @Override

       public void writeToParcel(Parcel dest, int flags) {

          dest.writeList(photoItems);

        }

 

       public static final Parcelable.Creator<ImageFolder> CREATOR = new Creator<ImageFolder>() {

         @Override

         public ImageFolder[] newArray(int size) {

              return new ImageFolder[size];

         }

         @Override

         public ImageFolder createFromParcel(Parcel source) {

            return new ImageFolder(source);

           }

        };

      如上代码,写入一个自定义对象的List可通过writeList实现;由于List本身已被序列化,所以读取List可通过readList。其中readList的参数,

       参数1:对象中的List本身,如photoItems

      参数2: List中的对象的ClassLoader,如List<ImageItem> photoItems,List的对象为ImageItem,因此参数为ImageItem.class.getClassLoader()

 

 

源码:

 

public class ImageItem implements Parcelable {

/**

* Image ID

*/

public String id;

/**

* Image路径

*/

public String path;

/**

* Image缩略路径

*/

public String thumbnailPath;

/**

* Image位图

*/

public Bitmap bitmap;

/**

* 根据路径获取Bitmap

*

* @param reqWidth

* @param reqHeight

* @return

*/

public Bitmap getBitmap(int reqWidth, int reqHeight) {

return ImageResizer.decodeSampledBitmapFromFile(path, reqWidth,

reqHeight);

}

@Override

public int describeContents() {

// 内容描述接口,默认返回0即可

return 0;

}

@Override

public void writeToParcel(Parcel dest, int flags) {

// 将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从

// Parcel容器获取数据

dest.writeString(id);

dest.writeString(path);

dest.writeString(thumbnailPath);

bitmap.writeToParcel(dest, 0);

}

/**

* 将Parcle对象映射为我的对象

*/

public static final Parcelable.Creator<ImageItem> CREATOR = new Parcelable.Creator<ImageItem>() {

@Override

public ImageItem createFromParcel(Parcel source) {

ImageItem item = new ImageItem();

item.id = source.readString();

item.path = source.readString();

item.thumbnailPath = source.readString();

item.bitmap = Bitmap.CREATOR.createFromParcel(source);

return item;

}

@Override

public ImageItem[] newArray(int size) {

return new ImageItem[size];

}

};

}

时间: 2024-08-29 17:44:44

Android开发系列之对象序列化的相关文章

C#程序员学习Android开发系列之ListView

上篇博客解决了Android客户端通过WebService与服务器端程序进行交互的问题,这篇博客重点关注两个问题,一个是Android应用程序如何与本机文件型数据库SQLite进行交互,另一问题则是如何在ListView中按照我们想要的界面效果进行展示.限于篇幅这篇重点讲ListView,下篇博客重点阐述SQLite. ListView是一个常用的数据显示控件,假设我们要做一个简单的界面,如图所示. 这张图是我直接从Android平板电脑(Android 4.2.2)上面截图下来的,就是一个普通

快速Android开发系列网络篇之Android-Async-Http

快速Android开发系列网络篇之Android-Async-Http 转:http://www.cnblogs.com/angeldevil/p/3729808.html 先来看一下最基本的用法 AsyncHttpClient client = new AsyncHttpClient(); client.get("http://www.google.com", new AsyncHttpResponseHandler() { @Override public void onSucce

快速Android开发系列网络篇之Retrofit

Retrofit是一个不错的网络请求库,用官方自己的介绍就是: A type-safe REST client for Android and Java 看官网的介绍用起来很省事,不过如果不了解它是怎么实现的也不太敢用,不然出问题了就不知道怎么办了.这几天比较闲就下下来看了一下,了解一下大概实现方法,细节就不追究了.先来看一个官网的例子,详细说明去网官看 简单示例 首先定义请求接口,即程序中都需要什么请求操作 public interface GitHubService { @GET("/use

C#程序员学习Android开发系列之SQLite

上篇博客提到过SQLite,它是嵌入式数据库,由于其轻巧但功能强大,被广泛的用于嵌入式设备当中.后来在智能手机.平板流行之后,它作为文件型数据库,几乎成为了智能设备单机数据库的必选,可以随着安卓app打包到apk文件当中. SQLite的官方网站是http://www.sqlite.org/,可以任意下载,上面也有详尽的文档可以参考,这篇博客重点关注SQLite在Android开发中如何使用. 在Android开发中,推荐建立一个类继承自SQLiteOpenHelper来创建数据库操作类,比如:

快速Android开发系列网络篇之Volley

Volley是Google推出的一个网络请求库,已经被放到了Android源码中,地址在这里,先看使用方法 RequestQueue mRequestQueue = Volley.newRequestQueue(context); JsonObjectRequest req = new JsonObjectRequest(URL, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONO

C#程序员学习Android开发系列之调用WebService

我在学习Android开发过程中遇到的第一个疑问就是Android客户端是怎么跟服务器数据库进行交互的呢?这个问题是我当初初次接触Android时所困扰我的一个很大的问题,直到几年前的一天,我突然想到WebService是否可以呢?让WebService充当服务器端的角色,完成与服务器数据库操作相关的事情,而Android客户端只要按照WebService方法参数的要求去调用就行了.在当时我对这个解决方案的实现还没模糊,我想这个问题也是初学Android的朋友肯定会想到的问题.那么现在就让我们动

Android开发系列(五):Android应用中文件的保存与读取

在本篇博客中,我们要实现在Android中"新建文件"和"读取文件": 目标界面: 在输入文件名称之后,输入文件内容,点击保存,可以保存成为一个文档 首先,我们先建立一个Android Project项目,项目名称:File. 然后,我们需要先实现目标视图中的界面: 编辑strings.xml文件: <?xml version="1.0" encoding="utf-8"?> <resources> &

C#程序员学习Android开发系列之按钮事件的4种写法

经过前两篇blog的铺垫,我们今天热身一下,做个简单的例子. 目录结构还是引用上篇blog的截图. 具体实现代码: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 方法1.

C#程序员学习Android开发系列之学习路线图

通过前面的3篇博客已经简单的介绍了Android开发的过程并写了一个简单的demo,了解了Android开发的环境以及一些背景知识. 接下来这篇博客不打算继续学习Android开发的细节,先停一下,明确一下接下来的学习目标以及学习路线. 一.对Android开发的基本认识 1.Android原生开发是基于Java语言的,由于我比较擅长C#,所以对Java语言本身不太熟练,需要加强Java语言基础的练习,这一块我会穿插到具体的知识点练习当中,并且在必要的地方给出与C#语言的对比(其实基本上在语法层