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