# 問題:兩個Activity之間如何傳遞數據呢?
Android中,在兩個Activity之間傳遞數據是一個常見的需求。
對于這個問題,可以分為兩個層面:
1.怎么將數據從Activity A傳遞給Activity B呢?
2.怎么將Activity A的參數傳遞給Activity B呢?
* * * * *
我們先來回答第2個問題,**怎么傳遞參數?**
毫無疑問,使用Intent的Bundle攜帶參數,實現在Activity之間傳遞參數傳遞。如傳遞基本數據類型可以使用:
~~~
intent.putExtra(key, value);
~~~
**除了傳遞基本類型外,如何傳遞自定義的對象呢**?
這里就涉及到本文想談論的Parcelable。Parcelable是Android提供的一個序列化接口。
在做開發的過程中,序列化是非常常見的。比如要將對象保存本地磁盤或者在網絡上傳輸等。實現序列化有兩種方式,一種是實現Serializable接口,第二種是實現Parcelable。
* * * * *
* Serializable與Parcelable的區別
1、Serializable是JDK提供的接口,而Parcelable是Android SDK提供的。
2、Serializable序列化是**基于磁盤**的,而Parcelable是**基于內存**的,效率比Serializable接口高效,可用于Intent數據傳遞,也可用于進程間通信(IPC)。
3、Serializalbe會使用反射,序列化和反序列化過程需要大量I/O操作,Parcelable自已實現封送和解封(marshalled &unmarshalled)操作不需要用反射,數據也存放在Native內存中,效率要快很多。
注:Bundle中既可以傳遞Parcelable對象,也可以傳遞Serializable對象
~~~
Bundle bundle = new Bundle();
bundle.putSerializable(String key, Serializable value);
bundle.putParcelable(String key, Parcelable value);
~~~
* * * * *
* Parcelable和Parcle這兩者之間的關系
Parcelable接口定義在封送/解封送過程中混合和分解對象的契約。
Parcelable接口的底層是**Parcel容器對象**。Parcel類是一種最快的序列化/反序列化機制,專為Android中的進程間通信而設計。**該類提供了一些方法來將成員容納到容器中,封裝后的數據可以通過Intent或IPC傳遞,除了基本類型外,只有實現了Parcelable接口的類才能放入parcel中。**
典型的Parcelable實現寫法如下:
~~~
public class PersonParcelable implements Parcelable {
private String name;
private int age;
protected PersonParcelable(Parcel in) {
name = in.readString();
age = in.readInt();
}
/**
* 內容描述接口
* @return
*/
@Override
public int describeContents() {
return 0;
}
/**
* 將類的數據寫到Parcel對象中,即將需要傳遞的數據打包到Parcel容器中,以便另一端從容器中讀取。
* @param out
* @param flags
*/
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(name);
out.writeInt(age);
}
public static final Creator<PersonParcelable> CREATOR = new Creator<PersonParcelable>() {
/**
* 從Parcel容器中讀取傳遞數據值,封裝成Parcelable對象返回邏輯層。
* @param in
* @return
*/
@Override
public PersonParcelable createFromParcel(Parcel in) {
return new PersonParcelable(in);
}
/**
* 供外部類反序列化本類數組使用
* @param size
* @return
*/
@Override
public PersonParcelable[] newArray(int size) {
return new PersonParcelable[size];
}
};
}
~~~
* * * * *
**在兩個Activity之前傳遞對象還要注意什么呢?**
一定要要注意對象的大小,Intent中的Bundle是在使用Binder機制進行數據傳遞的,能使用的Binder的緩沖區是有大小限制的(有些手機是2M),而一個進程默認有16個binder線程,所以一個線程能占用的緩沖區就更小了(以前做過測試,大約一個線程可以占用128KB)。所以當你看到“The Binder transaction failed because it was too large.”這類TransactionTooLargeException異常時,你應該知道怎么解決了。
因此,使用Intent在Activity之間傳遞List和Bitmap對象是有風險的。
另外注意:因為android不同版本Parcelable可能不同,所以不推薦使用Parcelable進行數據持久化。
* * * * *
接下來回答開始提出的第二個問題:如何將數據從Activity A傳遞到Activity B?
1.上面介紹過的,基于消息的通信機制 Intent--------boudle,extra。
2.利用static靜態數據,public static成員變量
3.基于外部存儲的傳輸 ,File/Preference/Sqlite,如果要針對第三方應用需要Content provider
4.基于Ipc的通信機制
5.基于Application Context