IPC基礎(chǔ)分享
這一章主要講述多進(jìn)程的作用,序列化和反序列化,Serializable和Parcelable
? IPC叫進(jìn)程間通信,指的是A進(jìn)程和B進(jìn)程交換信息。通常一個android應(yīng)用是一個進(jìn)程,一個進(jìn)程有一個主線程和多個子線程組成,在A進(jìn)程activity定義變量private static int i=1;并且讓i+1,輸出2,到了B進(jìn)程activity,獲取到的i的值還是1,這是因?yàn)锳ndroid多進(jìn)程間不能共享內(nèi)存。啟動多進(jìn)程期間,會再次啟動Application的生命周期,比如application類的oncreate等方法又執(zhí)行了一次。不過,在android有以下方法進(jìn)行進(jìn)程間交換數(shù)據(jù)
- bundle(用bundle和intent在兩個進(jìn)程傳遞數(shù)據(jù))
- 操作文件(讀寫操作同一個文件)
- AIDL(基于binder的通信方式,用aidl文件更加方便)
- Messenger(封裝后的aidl,只需用Messenger.send(message);即可發(fā)送信息)
- ContentProvider(讀寫數(shù)據(jù)庫)
- Socket(啟動本地的套接字來通信)
多進(jìn)程的作用
把應(yīng)用某個單獨(dú)的功能,單獨(dú)放在一個進(jìn)程中。
能給應(yīng)用獲取多份內(nèi)存空間
開啟多進(jìn)程
在AndroidManifest.xml文件給對應(yīng)的activity或者service設(shè)置以下屬性,其中值為:remote的進(jìn)程不能共享進(jìn)程資源,其他兩個值能共享,前提條件是在manifest標(biāo)簽配置相同的sharedUserId比如(android:sharedUserId="com.ppjun.sharedUserId"),還要讓兩個應(yīng)用配置相同的簽名。
<android:process=":remote"/> //對應(yīng)的進(jìn)程名是包名:remote
<android:process=".remote"/> //對應(yīng)的進(jìn)程名是包名.remote
<android:process="com.ppjun.remote"/> //對應(yīng)的進(jìn)程名是com.ppjun.remote
序列化和反序列化
- 序列化就是永久保存對象數(shù)據(jù)到文件中。
- 在activity或者service之間將對象序列化對象后通過intent等傳遞。
- 在多進(jìn)程之間也要將對象序列化后才能傳遞。
序列化是一個將對象變成字節(jié)的過程,發(fā)序列化是將這些字節(jié)重組成一個對象的過程。在Android中提供了Serializable和Parcelable接口序列化對象。
Serializable
讓類實(shí)現(xiàn)Serializable接口,并且指定一個long類型的serialVersionUID=xxxxL;xxxx為你自定義值
public class Student implements Serializable {
private static int final long serialVersionUID=213213123L
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
序列化student
Student student = new Student("jax");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("aa.txt").getName()));
oos.writeObject(student);
oos.close();
反序列化student
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("aa.txt")));
Student student2= (Student) ois.readObject();
ois.close();
此時的student2已經(jīng)不是原來的student了,是一個新的Student對象了。當(dāng)然這里沒寫serialVersionUID序列化和反序列也能成功運(yùn)行,系統(tǒng)默認(rèn)會計算出一個serialVersionUID。
當(dāng)你要在Student類加入id屬性加入,此時系統(tǒng)會計算出新的serialVersionUID,發(fā)序列化時,兩者serialVersionUID不同,反序列操作時就會報錯。所以一定要自定義一個serialVersionUID。
Parcelable
android api為我們提供的序列化類,也是要類實(shí)現(xiàn)Parcelable接口,重寫帶參數(shù)的構(gòu)造方法,writeToParcel方法,describeContents方法和new CREATOR對象呢重寫createFromParcel方法和newArray方法。
public class Book implements Parcelable {
public static final Creator<Book> CREATOR = new Creator<Book>() {
@Override
public Book createFromParcel(Parcel source) {
return new Book(source);
}
@Override
public Book[] newArray(int size) {
return new Book[size];
}
};
public int bookId;
public String bookName;
public Book(int bookId, String bookName) {
this.bookId = bookId;
this.bookName = bookName;
}
protected Book(Parcel parcel) {
bookId = parcel.readInt();
bookName = parcel.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(bookId);
dest.writeString(bookName);
}
@Override
public int describeContents() {
return 0;
}
public int getBookId() {
return bookId;
}
public void setBookId(int bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
兩者比較
- Serializable序列化同時產(chǎn)生大量臨時變量,導(dǎo)致gc頻繁;Serializable要通過io操作獲取獲取數(shù)據(jù),再寫入文件。
- Parcelable是以binder為信息載體,在內(nèi)存?zhèn)鬟f上開銷小。在讀寫數(shù)據(jù)時,Parcelable直接在內(nèi)存讀寫,所以Parcelable性能比Serializable好。
- 將對象序列化寫入文件,序列化對象進(jìn)行網(wǎng)絡(luò)傳輸建議選擇Serializable,對象要在activity等組件傳遞時,建議選擇Parcelable。