Android Parcelable

Intent 可以携带对象来在不同的Activity中传递数据,要传递的数据必须实现三个方法

1. describeContents()返回0就可以 、

2. writeToParcel(Parcel parcel, int flag) 把需要写入的数据写入Parcel中,然后框架调用此方法发送给接收端的Activity

3. public static final Parcelable.Creator<ParcelableObject> CREATOR 外部类反序列化该类时调用此方法

一定要注意:写入parcel和反序列化parcel时顺序一定要相同,不然数据会出错。

 ?[Copy to clipboard]Download zuiniuwang.java

 

 
  
  
  
  
  1.  /**  
  2.  * ParcelableObject.java  
  3.  * com.androidtest.parcelable  
  4.  *  
  5.  * Function: TODO  
  6.  *  
  7.  *   ver     date           author  
  8.  * ──────────────────────────────────  
  9.  *           2011-5-11      Leon  
  10.  *  
  11.  * Copyright (c) 2011, TNT All Rights Reserved.  
  12. */  
  13.    
  14. package com.androidtest.parcelable;  
  15.    
  16. import android.os.Parcel;  
  17. import android.os.Parcelable;  
  18.    
  19. /**  
  20.  * ClassName:ParcelableObject 需要实现三个方法,describeContents()返回0就可以 、 writeToParcel(Parcel parcel, int flag)  
  21.  * 写入Parcel和public static final Parcelable.Creator  
  22. <parcelableobject><span style="font-size: 14px"> CREATOR 供外部类反序列化该类  
  23.  * 一定要注意顺序后面这个两个函数读和写的顺序要相同,不然数据会出错  
  24.  * Function: TODO  
  25.  * Reason:   TODO ADD REASON  
  26.  *  
  27.  * @author   Leon  
  28.  * @version  
  29.  * @since    Ver 1.1  
  30.  * @Date     2011-5-11  
  31.  */  
  32. public class ParcelableObject implements Parcelable{  
  33.     private  String  name  ;  
  34.     private  String  surName ;  
  35.     private  int     age ;   
  36.    
  37.     public String getName() {  
  38.         return name;  
  39.     }  
  40.    
  41.     public void setName(String name) {  
  42.         this.name = name;  
  43.     }  
  44.    
  45.     public String getSurName() {  
  46.         return surName;  
  47.     }  
  48.    
  49.     public void setSurName(String surName) {  
  50.         this.surName = surName;  
  51.     }  
  52.    
  53.     public int getAge() {  
  54.         return age;  
  55.     }  
  56.    
  57.     public void setAge(int age) {  
  58.         this.age = age;  
  59.     }  
  60.    
  61.     @Override  
  62.     public int describeContents() {  
  63.    
  64.         // TODO Auto-generated method stub  
  65.         return 0;  
  66.    
  67.     }  
  68.    
  69.     @Override  
  70.     public void writeToParcel(Parcel dest, int flag) {  
  71.    
  72.         // TODO Auto-generated method stub  
  73.    
  74.         dest.writeInt(age);  
  75.         dest.writeString(name);  
  76.         dest.writeString(surName);  
  77.    
  78.     }  
  79.     public static final Parcelable.Creator CREATOR = new Creator() {  
  80.    
  81.         @Override  
  82.         public ParcelableObject createFromParcel(Parcel source) {  
  83.    
  84.             // TODO Auto-generated method stub  
  85.             ParcelableObject parcelableObj = new ParcelableObject();  
  86.             parcelableObj.age=source.readInt();  
  87.             parcelableObj.surName=source.readString();  
  88.             parcelableObj.name = source.readString();  
  89.             return parcelableObj;  
  90.    
  91.         }  
  92.    
  93.         @Override  
  94.         public ParcelableObject[] newArray(int size) {  
  95.    
  96.             // TODO Auto-generated method stub  
  97.             return new ParcelableObject[size];  
  98.    
  99.         }   
  100.    
  101.     };  

ParcelableActivity1 发送的代码

?[Copy to clipboard] Download zuiniuwang.java
 
 
  
  
  
  
  1. package com.androidtest.parcelable;  
  2.    
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.LinearLayout;  
  10. public class ParcelableActivity1 extends Activity {  
  11.    
  12.     @Override  
  13.     protected void onCreate(Bundle savedInstanceState) {  
  14.         // TODO Auto-generated method stub  
  15.         super.onCreate(savedInstanceState);  
  16.         LinearLayout linearLayout = new LinearLayout(this);  
  17.         Button button = new Button(this);  
  18.         button.setText("Send Parcelable Object");  
  19.         linearLayout.addView(button);  
  20.         button.setOnClickListener(new OnClickListener(){  
  21.             @Override  
  22.             public void onClick(View arg0) {  
  23.                 ParcelableObject passObject = new ParcelableObject();  
  24.                 passObject.setName("Leon Zhang");  
  25.                 passObject.setAge(18);  
  26.                 passObject.setSurName("xxx");  
  27.    
  28.                 Intent intent = new Intent(ParcelableActivity1.this,ParcelableActivity2.class);  
  29. //              使用Bundle发送  
  30. //              Bundle bundle = new Bundle();  
  31. //              bundle.putParcelable("key", passObject);  
  32.                 intent.putExtra("key", passObject);  
  33. //              intent.putExtras(bundle);  
  34.                 intent.putExtra("key2", "out of bundle");  
  35.                 startActivity(intent);  
  36.             }  
  37.         });  
  38.        this.setContentView(linearLayout);  
  39.     }  
  40.    

ParcelableActivity2 接收的代码

?[Copy to clipboard] Download zuiniuwang.java
 
 
  
  
  
  
  1. package com.androidtest.parcelable;  
  2.    
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.util.Log;  
  6.    
  7. public class ParcelableActivity2 extends Activity {  
  8.    
  9.     private static final String TAG = ParcelableActivity2.class.getSimpleName();  
  10.    
  11.     @Override  
  12.     protected void onCreate(Bundle savedInstanceState) {  
  13.    
  14.         // TODO Auto-generated method stub  
  15.         super.onCreate(savedInstanceState);  
  16.         ParcelableObject passObject = this.getIntent()  
  17.                 .getParcelableExtra("key");  
  18.    
  19.         Log.v(TAG, "Name: " + passObject.getName() + " Surname: "  
  20.                         + passObject.getSurName() + " Age: "  
  21.                         + String.valueOf(passObject.getAge())  
  22.                         + " out of bundle is :"  
  23.                         + this.getIntent().getStringExtra("key2"));  
  24.         Bundle myBundle = this.getIntent().getExtras();  
  25.         Log.v(TAG,"XX: "  
  26.                         + ((ParcelableObject) myBundle.getParcelable("key"))  
  27.                                 .getName()+ " Key2 :"+ myBundle.getString("key2"));  
  28.    
  29.     }  
  30.    

傻蛋经过测试发现,当使用Intent传递数据时,如果你自己创建了一个Bundle,则无论要传的数据是否放入Bundle(如直接intent.putExtra("xx" , "xx")),都会放到放到此Bundle中。如果没有创建此Bundle,则会默认创建一个Bundle来存放数据。当取数据时可以先取Bundle再从Bundle中取数据,或者直接取就好了。

如果要发送对象最简单的方法是: 把要发的数据直接当做对象发送,接收也不用Bundle,因为已经默认创建。

本文出自 “最牛傻蛋的博客” 博客,转载请与作者联系!


android 中自定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable。

一 序列化原因:

1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象。 

二 至于选取哪种可参考下面的原则:

1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。


实现:
1 Serializable 的实现,只需要继承  implements Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化。

2 Parcelabel 的实现,需要在类中添加一个静态成员变量 CREATOR,这个变量需要继承 Parcelable.Creator 接口。
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();
     }
 }


什么是Parcelable ?

     Parcelable,定义了将数据写入Parcel,和从Parcel中读出的接口。一个实体(用类来表示),如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为“可打包的”了。

 

Parcelable 传递对象

    Android序列化对象主要有两种方法:

    1.实现Serializable接口,实现Serializable接口是JavaSE本身就支持的;

    2.实现Parcelable接口,Parcelable是Android特有的功能,效率比实现Serializable接口高,像用于Intent数据传递也都支持,而且还可以用在进程间通信(IPC),

      除了基本类型外,只有实现了Parcelable接口的类才能被放入Parcel中。

 

Parcelable接口定义

复制代码
public interface Parcelable {
    //内容描述接口,基本不用管
    public int describeContents();
    //写入接口函数,打包
    public void writeToParcel(Parcel dest, int flags);
     //读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数传入。
    //为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例。
    public interface Creator<T> {
           public T createFromParcel(Parcel source);
           public T[] newArray(int size);
       }
复制代码

 

怎么实现Parcelable接口?

   从parcelable接口定义中,我们可以看到,实现parcelable接口,需要我们实现下面几个方法:

   1.describeContents方法。内容接口描述,默认返回0就可以;

   2.writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.即打包需要传递的数据到Parcel容器保存,以便从parcel容器获取数据,该方法声明如下:

     writeToParcel (Parcel dest, int flags) 具体参数含义见javadoc

   3.静态的Parcelable.Creator接口,本接口有两个方法:

     createFromParcel(Parcel in)  从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层。

     newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。方法是供外部类反序列化本类数组使用。

 

代码实现

    1.封装数据,把实现parcelable接口的Person对象传递到TwoActivity里;

复制代码
public class DemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 封装数据
        Person p = new Person();
        p.setId(1);
        p.setName("xiaoming");
        // 用Intent传递Person对象
        Intent i = new Intent(this, TwoActivity.class);
        i.putExtra("Person", p);
        startActivity(i);
    }
}
复制代码

 

   2.TwoActivity获取数据,从DemoActivity传递的Person对象给解析,并打印;

   

复制代码
public class TwoActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        
        Person p = (Person)getIntent().getParcelableExtra("Person");
        
        System.out.println("p_id"+p.getId());
        System.out.println("p_name"+p.getName());
    }
}
复制代码

 

3.parcelable接口的实现

复制代码
 1 public class Person implements Parcelable{
 2     
 3     // 成员变量
 4     private int id;
 5     private String name;
 6     
 7     // 1.必须实现Parcelable.Creator接口,否则在获取Person数据的时候,会报错,如下:
 8     // android.os.BadParcelableException:
 9     // Parcelable protocol requires a Parcelable.Creator object called  CREATOR on class com.um.demo.Person
10     // 2.这个接口实现了从Percel容器读取Person数据,并返回Person对象给逻辑层使用
11     // 3.实现Parcelable.Creator接口对象名必须为CREATOR,不如同样会报错上面所提到的错;
12     // 4.在读取Parcel容器里的数据事,必须按成员变量声明的顺序读取数据,不然会出现获取数据出错
13     // 5.反序列化对象
14     public static final Parcelable.Creator<Person> CREATOR = new Creator(){
15 
16         @Override
17         public Person createFromParcel(Parcel source) {
18             // TODO Auto-generated method stub
19             // 必须按成员变量声明的顺序读取数据,不然会出现获取数据出错
20             Person p = new Person();
21             p.setId(source.readInt());
22             p.setName(source.readString());
23             return p;
24         }
25 
26         @Override
27         public Person[] newArray(int size) {
28             // TODO Auto-generated method stub
29             return new Person[size];
30         }
31     };
32     
33     public int getId() {
34         return id;
35     }
36 
37     public void setId(int id) {
38         this.id = id;
39     }
40 
41     public String getName() {
42         return name;
43     }
44 
45     public void setName(String name) {
46         this.name = name;
47     }
48 
49     @Override
50     public int describeContents() {
51         // TODO Auto-generated method stub
52         return 0;
53     }
54 
55     @Override
56     public void writeToParcel(Parcel dest, int flags) {
57         // TODO Auto-generated method stub
58         // 1.必须按成员变量声明的顺序封装数据,不然会出现获取数据出错
59         // 2.序列化对象
60         dest.writeInt(id);
61         dest.writeString(name);
62     }
63 }
复制代码

 

 

好了,parcelable接口的实现,到处结束!!

 

转载请注明出处:http://www.cnblogs.com/hpboy


你可能感兴趣的:(Android Parcelable)