8-12号:
又遇到一奇葩错误,晕死了
在项目中遇到一个错误,唉,如果直接在项目汇总修改的话,每次要麻烦别人添加签名才能运行调试,所以自己干脆写个例子,把这个坑刨的更深一点吧
一看错误信息,就知道是在数据传递过程中,序列化异常,但是我的实体对象Finger已经实现了Serializable接口,如下:
上网查资料,才知道,原来,传递Serializable对象时,被传递的Serializable对象里面的自定义成员对象(非API中的Serializable对象)也要实现Serializable接口,也就是实体类中的Bitmap,否则会出现Caused by: java.io.NotSerializableException异常.
好吧,那我看了Bitmap的API之后,发现,Bitmap已经实现了Parcelable接口,(对象序列化,有两种方法,一种是实现Serializable接口,一种是实现Parcelable,至于两中实现方式有什么区别,在此不care),所以,那我就直接吧对象改成实现Parcelable接口:
如下:
实现Parcelable接口,必须实现以下两个方法:
1 @Override 2 public int describeContents() { 3 // TODO Auto-generated method stub 4 return 0; 5 } 6 @Override 7 public void writeToParcel(Parcel dest, int flags) { 8 // TODO Auto-generated method stub 9 10 }
1)describeContents方法:内容接口描述,默认返回0就可以;
2)writeToParcel 方法:该方法将类的数据写入外部提供的Parcel中.即打包需要传递的数据到Parcel容器保存,以便从parcel容器获取数据,该方法声明如下:
writeToParcel (Parcel dest, int flags) 具体参数含义见doc文档:其实就是将对象序列化为一个Parcel对象。
贴代码:
第一个测试Activity:
1 public class MainActivity extends Activity { 2 3 private Finger f = new Finger(); 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_main); 8 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); 9 f.setBmp(bitmap); 10 f.setName("拇指"); 11 Button btn = (Button)findViewById(R.id.btn); 12 btn.setOnClickListener(new OnClickListener() { 13 14 @Override 15 public void onClick(View v) { 16 // TODO Auto-generated method stub 17 Intent intent = new Intent(MainActivity 18 .this,SecondActivity.class); 19 Bundle b = new Bundle(); 20 b.putParcelable("info", f); 21 intent.putExtras(b); 22 startActivity(intent); 23 24 } 25 }); 26 }
第二个测试Activity:
1 public class SecondActivity extends Activity{ 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 // TODO Auto-generated method stub 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_sec); 8 ImageView iv = (ImageView)findViewById(R.id.iv); 9 Intent i = getIntent(); 10 Bundle b = i.getExtras(); 11 Finger f = (Finger) b.getParcelable("info"); 12 iv.setImageBitmap(f.getBmp()); 13 14 } 15 }
实体对象Finger:
1 package com.example.test; 2 3 import android.graphics.Bitmap; 4 import android.os.Parcel; 5 import android.os.Parcelable; 6 7 public class Finger implements Parcelable { 8 9 private String name; 10 private Bitmap bmp; 11 12 /** 13 * get set方法 14 */ 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public Bitmap getBmp() { 24 return bmp; 25 } 26 27 public void setBmp(Bitmap bmp) { 28 this.bmp = bmp; 29 } 30 31 /** 32 * 內容接口描述 33 */ 34 @Override 35 public int describeContents() { 36 // TODO Auto-generated method stub 37 return 0; 38 } 39 40 /** 41 * 將数据写入Parcel容器,由Parcel容器保存,以便从parcel容器获取数据 42 */ 43 @Override 44 public void writeToParcel(Parcel dest, int flags) { 45 // TODO Auto-generated method stub 46 dest.writeString(name); 47 dest.writeParcelable(bmp, flags); 48 49 } 50 51 /** 52 * 静态的Parcelable.Creator接口 53 * 其中public static final这几个修饰符一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。 54 */ 55 public static final Parcelable.Creator<Finger> CREATOR = new Parcelable.Creator<Finger>() { 56 57 /** 58 * 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层 59 */ 60 @Override 61 public Finger createFromParcel(Parcel source) { 62 // TODO Auto-generated method stub 63 return new Finger(source); 64 } 65 66 /** 67 * 仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。 68 */ 69 @Override 70 public Finger[] newArray(int size) { 71 // TODO Auto-generated method stub 72 return new Finger[size]; 73 } 74 75 }; 76 77 public Finger() { 78 79 } 80 81 private Finger(Parcel in) { 82 name = in.readString(); 83 bmp = in.readParcelable(Bitmap.class.getClassLoader()); 84 ; 85 86 } 87 88 }
参考:
http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html