IPC是Inter-Process Communication的縮寫濒析,也就是進(jìn)程間的通訊正什,任何一個(gè)操作系統(tǒng)都有著自己的IPC,Android系統(tǒng)同樣的不例外.眾所周知号杏,Android是基于Linux的一個(gè)移動操作系統(tǒng)埠忘,但它的IPC不同于Linux,Android有自己獨(dú)特的Binder馒索。另外莹妒,Android應(yīng)用程序時(shí)用Java語言進(jìn)行開發(fā),同樣的我們還可以用Java的Socket來進(jìn)行IPC绰上。
進(jìn)程和線程
??進(jìn)程旨怠,官方的說法是cpu執(zhí)行的最小單元,相信好多人看到這句話就懵逼了蜈块,什么是最小的單元鉴腻?簡單的說,大部分情況下就是操作系統(tǒng)上的個(gè)正在運(yùn)行的應(yīng)用百揭。聽了是不是瞬間神清氣爽八ァ!
??那什么是線程呢器一?舉個(gè)實(shí)際的例子吧课锌,我是 建筑大學(xué)畢業(yè)的數(shù)學(xué)系學(xué)渣,在這種學(xué)校里自然就會有很多干建筑相關(guān)這一行的同學(xué)祈秕,所以很多同學(xué)上了工地渺贤,那工地上就有許許多多辛苦的工人。那么请毛,進(jìn)程就是工地志鞍,線程就是這個(gè)工地上的工人,一個(gè)工地有很多工人同時(shí)干活方仿,那也就是說一個(gè)進(jìn)程可以同時(shí)讓多個(gè)線程分別執(zhí)行不同的任務(wù)固棚,這樣是不是就大大提高了效率。所以進(jìn)程和線程之間是包含的關(guān)系仙蚜。
??嘮了了這么多此洲,那多進(jìn)程在Android中體現(xiàn)在哪里?
- 不同的應(yīng)用之間需要數(shù)據(jù)交流
- ContentProvider獲取其他應(yīng)用的數(shù)據(jù)
- AIDL執(zhí)行其他應(yīng)用的Service
- 通常情況下鳍征,一個(gè)進(jìn)程只有一份指定大小的內(nèi)存空間可以用黍翎,科室但一個(gè)應(yīng)用的內(nèi)存不夠用時(shí),可以怎么辦艳丛?在本應(yīng)用內(nèi)再開一個(gè)進(jìn)程匣掸,這樣就能使用兩份內(nèi)存空間了emoji:[笑著哭]。這個(gè)時(shí)候IPC就顯得格外重要
開啟Android應(yīng)用的多進(jìn)程
??很簡單氮双,通過四大組件在Androidmanifest.xml注冊時(shí)指定屬性andoid:process就可以輕松開啟新的進(jìn)程
<activity android:name=".a.OpenMutiProcessAty"android:process="com.hk.remote"/>
??一旦打開了這個(gè)Activity碰酝,該應(yīng)用會再次創(chuàng)建Application,也就是是兩個(gè)一模一樣的應(yīng)用在系統(tǒng)同時(shí)run戴差,可以打開ddms或者shell查看送爸,發(fā)現(xiàn)兩個(gè)不同pid進(jìn)程在跑,這說明當(dāng)一個(gè)組件跑在新的進(jìn)程的時(shí)候,系統(tǒng)會分配獨(dú)立的虛擬機(jī)袭厂。
??android:process這個(gè)屬性值還可以這么寫com.hk:remote
或者:remote
,那么這種寫法與com.hk.remote
有什么區(qū)別呢墨吓?首先,:remote
是com.hk:remote
的簡寫纹磺,其次帖烘,進(jìn)程名以“:”開頭的進(jìn)程屬于當(dāng)前應(yīng)用的私有進(jìn)程,其他 應(yīng)用不可以和它跑在同一個(gè)進(jìn)程中橄杨,否則可以通過ShareID方式使進(jìn)程共享秘症。
對象的序列化
IPC的時(shí)候進(jìn)程會傳遞對象,但傳遞的對象必須經(jīng)過序列化式矫,序列化的方式有兩種
Serializable和Parcelable
- Serializable的使用
- Serializable是Java提供的一個(gè)序列化接口乡摹,他是一個(gè)空接口,創(chuàng)建一個(gè)類person
public class Person implements Serializable {
private static final long serialVersionUID = 6L;
private String name;
private int age;
//Constructor and Getter/Setter
//...
}
>serialVersionUID可寫可不寫采转,但存在即合理聪廉,建議手工指定,因?yàn)榭梢蕴岣叻葱蛄谢某晒β适弦濉P蛄谢臅r(shí)候系統(tǒng)會把當(dāng)前類的serialVersionUID寫入序列化文件中(也可能是其他)锄列,當(dāng)反序列化的時(shí)候系統(tǒng)回去檢測文件中的serialVersionUID,看它是否已當(dāng)前類的serialVersionUID一直惯悠,如果一致就說明序列化的類的版本和當(dāng)前類的版本相同邻邮,這個(gè)時(shí)候可以成功反序列化,如果不指定serialVersionUID的值克婶,系統(tǒng)在序列化的時(shí)候會根據(jù)類的結(jié)構(gòu)自動生成serialVersionUID筒严,并寫入序列化文件中,如果反序列化的時(shí)候情萤,當(dāng)前類走了修改鸭蛙,則反序列化時(shí)的serialVersionUID就會重新生成,造成serialVersionUID不一致反序列化失敗筋岛,所以如果手動指定serialVersionUID娶视,類結(jié)構(gòu)發(fā)生變化,系統(tǒng)仍然能最大限度的恢復(fù)數(shù)據(jù)睁宰,而不會讓程序崩潰肪获。
2. 序列化
Person person = new Person("hvcker",22);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(person);
out.close();
3. 反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));
Person p = (Person) in.readObject();
in.close();
* Parcelable的使用
Parcelable也是一個(gè)接口,實(shí)現(xiàn)這個(gè)接口就可以實(shí)現(xiàn)序列化
public class User implements Parcelable {
private int id;
private String userName;
//Constructor and Getter/Setter
//...
protected User(Parcel in) {
id = in.readInt();
userName = in.readString();
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(userName);
}
}
| 方法 | 功能 | 所屬類 |
| -------- | --------| -- |
| createFromParcel(Parcel in)| 從序列化后的對象中創(chuàng)建原始對象 |User.CREATOR|
| newArray(int size)|創(chuàng)建指定長度的原始對象數(shù)組|User.CREATOR|
| writeToParcel(Parcel dest, int flags)|將當(dāng)前對象寫入序列化結(jié)構(gòu)中柒傻,其中flags標(biāo)識有兩種:0或者1孝赫。為1時(shí)當(dāng)前對象需要作為返回值返回,不能立即釋放資源红符,幾乎所有情況都為0|User|
|describeContents()|返回當(dāng)前對象的內(nèi)容描述青柄,如果含有文件描述符伐债,返回1,否則返回0致开,幾乎所有情況都返回0|User|
> Serializable是Java中的序列化接口峰锁,使用起來簡單但開銷很大,序列化和反序列化過程是I/O操作的過程;Parcelable是Android提供的序列化方式喇喉,因此更適合用在Android平臺上祖今,parcelable主要用在內(nèi)存序列化上,但通過parcelable將對象序列化到存儲設(shè)備中或者將對象 序列化后通過網(wǎng)絡(luò)傳輸這個(gè)過程很復(fù)雜拣技,這種情況下建議用Serializable。