Android多程序通訊
原文來自:https://juejin.im/post/5aa08cb3f265da23766ad734 本人僅供學習筆記,如有侵權,請告知,我會刪除!
一、Android 中的多程序
1、定義:
首先,程序一般指一個執行單元,在移動裝置上就是一個程式或應用,我們在Android中所說的多程序(IPC)一般指一個應用包含多個程序。之所以要使用多程序有兩方面原因:某些模組由於特殊的需求要執行在單獨的程序;增加應用可用的記憶體空間。
2、開啟多程序
Android中開啟多執行緒只有一種方法,就是在AndroidManifest.xml中註冊Service、Activity、Receiver、ContentProvider時指定
android:process
屬性,例如:<service
android:name=".MyService"
android:process=":remote">
</service>
<activity
android:name=".MyActivity"
android:process="com.shh.ipctest.remote2">
</activity>
我們為MyService
和MyActivity
指定的android:process
屬性值有所不同,它們的區別如下:
:remote
:以:
開頭是一種簡寫,系統會在當前程序名前附件當前包名,完整的程序名為:com.shh.ipctest:remote
:
開頭的程序屬於當前應用的私有程序,其它應用的元件不能和它跑在同一程序。com.shh.ipctest.remote2
:這是完整的命名方式,不會附加包名,其它應用如果和該程序的ShareUID
、簽名
相同,則可以和它跑在同一個程序,實現資料共享。
3、多程序引發的問題
開啟多程序雖簡單,但會引發如下問題,必須引起注意。
- 靜態成員和單例模式失效
- 執行緒同步機制失效
- SharedPreferences 可靠性降低
- Application 被多次建立
對於前兩個問題,可以這麼理解,在Android中,系統會為每個應用或程序分配獨立的虛擬機器,不同的虛擬機器自然佔有不同的記憶體地址空間,所以同一個類的物件會產生不同的副本,導致共享資料失敗,必然也不能實現執行緒的同步。
由於SharedPreferences
底層採用讀寫XML的檔案的方式實現,多程序併發的的讀寫很可能導致資料異常。
Application
被多次建立和前兩個問題類似,系統在分配多個虛擬機器時相當於把同一個應用重新啟動多次,必然會導致 Application 多次被建立,為了防止在 Application中出現無用的重複初始化,可使用程序名來做過濾,只讓指定程序的才進行全域性初始:
public class MyApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
String processName = "com.shh.ipctest";
if (getPackageName().equals(processName)){
// do some init
}
}
4、Android中的多程序通訊方式
Android中支援的多程序通訊方式主要有以下幾種,它們之間各有優缺點,可根據使用場景選擇選擇:
- AIDL:功能強大,支援程序間一對多的實時併發通訊,並可實現 RPC (遠端過程呼叫)。
- Messenger:支援一對多的序列實時通訊, AIDL 的簡化版本。
- Bundle:四大元件的程序通訊方式,只能傳輸 Bundle 支援的資料型別。
- ContentProvider:強大的資料來源訪問支援,主要支援 CRUD 操作,一對多的程序間資料共享,例如我們的應用訪問系統的通訊錄資料。
- BroadcastReceiver:即廣播,但只能單向通訊,接收者只能被動的接收訊息。
- 檔案共享:在非高併發情況下共享簡單的資料。
- Socket:通過網路傳輸資料。
這裡我們主要討論四大元件中Service在多程序通訊中的使用,這就涉及到了 AIDL、Messenger這兩種多程序通訊方式,接下來重點看這兩種 IPC 方式。
二、AIDL
AIDL 的意思是 Android 介面定義語言,使用AIDL進行程序間通訊需要定義服務端和客戶端,其中客戶端和服務端可以在同一應用也可以在不同應用。這裡我們服務端可以看做是圖書館,為客戶端提供近期新書查詢、圖書捐贈、新書通知的服務。三、Binder
在 AIDL 的例子中,客戶端之所以能和服務端通訊,主要依靠系統提供的Binder
類實現,它實現了IBinder
介面,我們在前邊的例子已經用到了Binder
類,例如在服務端的 Service 中建立了一個Binder
物件並在onBind()
中返回:
四、Messenger
Messenger
是一種輕量級的多程序通訊方式,它是在 AIDL 的基礎上封裝而成的,可以看做是 AIDL 的簡化版,支援一對多的序列實時通訊,一次只處理一個請求,不存在併發的問題。和 AIDL 的使用類似,但要簡單的多,同樣需要實現服務端和客戶端。