探索Android中的Parcel机制(下)

来源:互联网 发布:舒畅和刘亦菲关系知乎 编辑:程序博客网 时间:2024/06/10 14:47

上一篇中我们透过源码看到了Parcel背后的机制,本质上把它当成一个Serialize就可以了,只是它是在内存中完成的序列化和反序列化,利用的是连续的内存空间,因此会更加高效。

         我们接下来要说的是Parcel类如何应用。就应用程序而言,最常见使用Parcel类的场景就是在Activity间传递数据。没错,在Activity间使用Intent传递数据的时候,可以通过Parcelable机制传递复杂的对象。

         在下面的程序中,MyColor用于保存一个颜色值,MainActivity在用户点击屏幕时将MyColor对象设成红色,传递到SubActivity中,此时SubActivity的TextView显示为红色的背景;当点击SubActivity时,将颜色值改为绿色,返回MainActivity,期望的是MainActivity的TextView显示绿色背景。

         来看一下MyColor类的实现代码:

        

[java] view plaincopy
  1. package com.wenbin.test;  
  2.   
  3. import android.graphics.Color;  
  4. import android.os.Parcel;  
  5. import android.os.Parcelable;  
  6.   
  7. /** 
  8.  * @author 曹文斌 
  9.  * http://blog.csdn.net/caowenbin 
  10.  * 
  11.  */  
  12. public class MyColor implements Parcelable {  
  13.     private int color=Color.BLACK;  
  14.       
  15.     MyColor(){  
  16.         color=Color.BLACK;  
  17.     }  
  18.       
  19.     MyColor(Parcel in){  
  20.         color=in.readInt();  
  21.     }  
  22.       
  23.     public int getColor(){  
  24.         return color;  
  25.     }  
  26.       
  27.     public void setColor(int color){  
  28.         this.color=color;  
  29.     }  
  30.       
  31.     @Override  
  32.     public int describeContents() {  
  33.         return 0;  
  34.     }  
  35.   
  36.     @Override  
  37.     public void writeToParcel(Parcel dest, int flags) {  
  38.         dest.writeInt(color);  
  39.     }  
  40.   
  41.     public static final Parcelable.Creator<MyColor> CREATOR  
  42.         = new Parcelable.Creator<MyColor>() {  
  43.         public MyColor createFromParcel(Parcel in) {  
  44.             return new MyColor(in);  
  45.         }  
  46.           
  47.         public MyColor[] newArray(int size) {  
  48.             return new MyColor[size];  
  49.         }  
  50.     };  
  51. }  

 

         该类实现了Parcelable接口,提供了默认的构造函数,同时也提供了可从Parcel对象开始的构造函数,另外还实现了一个static的构造器用于构造对象和数组。代码很简单,不一一解释了。

         再看MainActivity的代码:

 

[java] view plaincopy
  1. package com.wenbin.test;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.graphics.Color;  
  6. import android.os.Bundle;  
  7. import android.view.MotionEvent;  
  8.   
  9. /** 
  10.  * @author 曹文斌 
  11.  * http://blog.csdn.net/caowenbin 
  12.  * 
  13.  */  
  14. public class MainActivity extends Activity {  
  15.     private final int SUB_ACTIVITY=0;  
  16.     private MyColor color=new MyColor();  
  17.       
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.main);  
  22.     }  
  23.   
  24.     @Override  
  25.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  26.         super.onActivityResult(requestCode, resultCode, data);  
  27.         if (requestCode==SUB_ACTIVITY){  
  28.             if (resultCode==RESULT_OK){  
  29.                 if (data.hasExtra("MyColor")){  
  30.                     color=data.getParcelableExtra("MyColor");  //Notice  
  31.                     findViewById(R.id.text).setBackgroundColor(color.getColor());  
  32.                 }  
  33.             }  
  34.         }  
  35.     }  
  36.   
  37.     @Override  
  38.     public boolean onTouchEvent(MotionEvent event){  
  39.         if (event.getAction()==MotionEvent.ACTION_UP){  
  40.             Intent intent=new Intent();  
  41.             intent.setClass(this, SubActivity.class);  
  42.             color.setColor(Color.RED);  
  43.             intent.putExtra("MyColor", color);  
  44.             startActivityForResult(intent,SUB_ACTIVITY);      
  45.         }  
  46.         return super.onTouchEvent(event);  
  47.     }  
  48.   
  49. }  

 

        下面是SubActivity的代码:

 

[java] view plaincopy
  1. package com.wenbin.test;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.graphics.Color;  
  6. import android.os.Bundle;  
  7. import android.view.MotionEvent;  
  8. import android.widget.TextView;  
  9.   
  10. /** 
  11.  * @author 曹文斌 
  12.  * http://blog.csdn.net/caowenbin 
  13.  * 
  14.  */  
  15. public class SubActivity extends Activity {  
  16.     private MyColor color;  
  17.       
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.main);  
  22.         ((TextView)findViewById(R.id.text)).setText("SubActivity");  
  23.         Intent intent=getIntent();  
  24.         if (intent!=null){  
  25.             if (intent.hasExtra("MyColor")){  
  26.                 color=intent.getParcelableExtra("MyColor");  
  27.                 findViewById(R.id.text).setBackgroundColor(color.getColor());  
  28.             }  
  29.         }  
  30.     }  
  31.       
  32.     @Override  
  33.     public boolean onTouchEvent(MotionEvent event){  
  34.         if (event.getAction()==MotionEvent.ACTION_UP){  
  35.             Intent intent=new Intent();  
  36.             if (color!=null){  
  37.                 color.setColor(Color.GREEN);  
  38.                 intent.putExtra("MyColor", color);  
  39.             }  
  40.             setResult(RESULT_OK,intent);  
  41.             finish();  
  42.         }  
  43.         return super.onTouchEvent(event);  
  44.     }  
  45. }  

 

        下面是main.xml的代码:

 

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <TextView    
  8.     android:layout_width="fill_parent"   
  9.     android:layout_height="wrap_content"   
  10.     android:text="@string/hello"  
  11.     android:id="@+id/text"  
  12.     />  
  13. </LinearLayout>  

 

        注意的是在MainActivity的onActivityResult()中,有一句color=data.getParcelableExtra("MyColor"),这说明的是反序列化后是一个新的MyColor对象,因此要想使用这个对象,我们做了这个赋值语句。

         记得在上一篇《探索Android中的Parcel机制(上)》中提到,如果数据本身是IBinder类型,那么反序列化的结果就是原对象,而不是新建的对象,很显然,如果是这样的话,在反序列化后在MainActivity中就不再需要color=data.getParcelableExtra("MyColor")这句了。因此,换一种MyColor的实现方法,令其中的int color成员变量使用IBinder类型的成员变量来表示。

         新建一个BinderData类继承自Binder,代码如下:

 

[java] view plaincopy
  1. package com.wenbin.test;  
  2.   
  3. import android.os.Binder;  
  4.   
  5. /** 
  6.  * @author 曹文斌 
  7.  * http://blog.csdn.net/caowenbin 
  8.  * 
  9.  */  
  10. public class BinderData extends Binder {  
  11.     public int color;  
  12. }  

  

       修改MyColor的代码如下:

 

[java] view plaincopy
  1. package com.wenbin.test;  
  2.   
  3. import android.graphics.Color;  
  4. import android.os.Parcel;  
  5. import android.os.Parcelable;  
  6.   
  7. /** 
  8.  * @author 曹文斌 
  9.  * http://blog.csdn.net/caowenbin 
  10.  * 
  11.  */  
  12. public class MyColor implements Parcelable {  
  13.     private BinderData data=new BinderData();  
  14.       
  15.     MyColor(){  
  16.         data.color=Color.BLACK;  
  17.     }  
  18.       
  19.     MyColor(Parcel in){  
  20.         data=(BinderData) in.readValue(BinderData.class.getClassLoader());  
  21.     }  
  22.       
  23.     public int getColor(){  
  24.         return data.color;  
  25.     }  
  26.       
  27.     public void setColor(int color){  
  28.         data.color=color;  
  29.     }  
  30.       
  31.     @Override  
  32.     public int describeContents() {  
  33.         return 0;  
  34.     }  
  35.   
  36.     @Override  
  37.     public void writeToParcel(Parcel dest, int flags) {  
  38.         dest.writeValue(data);  
  39.     }  
  40.   
  41.     public static final Parcelable.Creator<MyColor> CREATOR  
  42.         = new Parcelable.Creator<MyColor>() {  
  43.         public MyColor createFromParcel(Parcel in) {  
  44.             return new MyColor(in);  
  45.         }  
  46.           
  47.         public MyColor[] newArray(int size) {  
  48.             return new MyColor[size];  
  49.         }  
  50.     };  
  51. }  

         去掉MainActivity的onActivityResult()中的color=data.getParcelableExtra("MyColor")一句,变成:

 

[java] view plaincopy
  1. @Override  
  2. protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  3.     super.onActivityResult(requestCode, resultCode, data);  
  4.     if (requestCode==SUB_ACTIVITY){  
  5.         if (resultCode==RESULT_OK){  
  6.             if (data.hasExtra("MyColor")){  
  7.                 findViewById(R.id.text).setBackgroundColor(color.getColor());  
  8.             }  
  9.         }  
  10.     }  
  11. }  

         再次运行程序,结果符合预期。

 

         以上就是Parcel在应用程序中的使用方法,与Serialize还是挺相似的,详细的资料当然还是要参考Android SDK的开发文档了。

——欢迎转载,请注明出处 http://blog.csdn.net/caowenbin ——

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 20天大的宝宝4天不拉大便怎么办 还不会说话的小孩子脾气大怎么办 两岁的宝宝说话变的口吃怎么办 37周b超宝宝腿短怎么办 3岁的宝宝说话说不好怎么办 小儿说话晚的原因宝宝说话晚怎么办 22岁的儿子在家不说话怎么办 儿子2周4个月了不说话怎么办 三岁的宝宝还不会数数怎么办 2岁宝宝晚上不睡觉不听话怎么办 8个月的狗狗怕人不敢出门怎么办 狗太怕人了怎么办都不敢出门 媳妇和婆婆晚上都不想带孩子怎么办 婆婆和媳妇带孩子观念不一样怎么办 婆婆给媳妇买了不喜欢的家具怎么办 断奶后宝宝对奶粉很抗拒怎么办 两岁宝宝断奶不喝奶粉怎么办 宝宝两岁了断奶后奶粉不吃怎么办 宝宝断奶两天了不愿意吃奶粉怎么办 一岁四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶后不吃奶粉怎么办 2岁的宝宝不开口说话怎么办 一周岁宝宝断奶不喝奶粉怎么办 八个月宝宝断奶不喝奶粉怎么办 婆家人总是用心机对待娘家人怎么办 婆婆老是背后说我娘家人坏话怎么办 婆家姐带孩子住娘家不走怎么办? 老是想在娘家不想回婆家怎么办 娘家和婆家同时向我借钱怎么办 土地确权后娘家婆家都没有怎么办 结了婚婆家向娘家借钱怎么办? 婆婆的娘家人从我家住怎么办 八个月宝宝断奶后不吃奶粉怎么办 吃母乳的宝宝不吸奶嘴怎么办 宝宝吸了奶嘴不吸母乳怎么办 婴儿吃了奶嘴不吸母乳怎么办 十一个月宝宝断奶不喝奶粉怎么办 孩子三门成绩全不及格家长该怎么办 宝宝快十个月了还不会爬怎么办 小孩写字老把手向里扭曲怎么办