進程名以":"開頭的講程屬於當前應用的私有進程,其餘應用的組件不能夠和它跑在同一個進程中,而進程名不以開頭的進程屬於全局進程, 其餘應用經過ShareUID方式能夠和它跑在同一個進程中。緩存
咱們知道Andrid系統會爲每一個應用分配一個惟一的UID,具備相同UID的應用才能共享數據。這裏要說明的是,兩個應用經過ShareUID跑在同一個進程中是有要求的,須要這兩個應用有相同的ShareUID而且簽名相同才能夠。在這種狀況下,它們能夠互相訪問對方的私有數據,好比data目錄、組件信息等,無論它們是否跑在同一個進程中。 固然若是它們跑在同一個進程中,那麼除了能共享data目錄、組件信息,還能夠共享內存數據,或者說它們看起來就像是一個應用 的兩個部分。bash
Messenger能夠翻譯爲信使,顧名思義,經過它能夠在不一樣進程中傳遞Mesge對象, 在Message中放入咱們須要傳遞的數據,就能夠輕鬆地實現數據的進程間傳遞了網絡
服務端進程socket
首先,咱們須要在服務端建立一個Service來處理客戶端的鏈接請求,同時建立一個Handler並經過它來建立個Messenger對象,而後在Service的onBind中返回這個Messenger對象底層的Binder便可。ide
客戶端進程ui
客戶端進程中,首先要綁定服務端的Service, 綁定成功後用服務端返回的IBinder 對 象建立一個Messenger,經過這個Messenger 就能夠向服務端發送消息了,發消息類型爲 Message 對象。若是須要服務端可以迴應客戶端,就和服務端一*樣,咱們還須要建立 一個 Handler並建立一個新的Messenger, 並把這個Messenger對象經過Message的replyTo參數 傳遞給服務端,服務端經過這個replyTo參數就能夠迴應客戶端。spa
直觀來講,Binder 是Android中的一個類, 它實現了IBinder 接口。從IPC 角度來講, Binder是Android中的一種跨進 程通訊方式,Binder 還能夠理解爲一種虛擬的物理設備,它的設備驅動是/dev/binder,該通訊方式在Linux中沒有;從Android Framework角度來講Binder是ServiceManager鏈接各類Manager (ActivityManager、WindowManager,等等)相應ManagerService的橋樑;線程
從Android 應用層來講,Binder 是客戶端和服務端進行通化的媒介,當bindService 的時候,服務端會返回一一個包含了服務端業務調用的Binder對象經過這個Binder對象,客戶端就能夠獲取服務端提供的服務或者數據,這裏的服務包括通服務和基於AIDL的服務。翻譯
Android開發中,Binder主要用在Service中,包括AIDL和Messenger,其中普通Serv中的Binder不涉及進程間通訊,因此較爲簡單,沒法觸及Binder的核心,而Messenget底層實際上是AIDL。代理
aidl文件中使用了自定義的Parcelable對象和aidl對象必須顯式import進來,同一個包路徑下也要導入
aidl文件中使用了自定義的Parcelable對象,那必須建立一個和自定義的Parcelable對象同名的aidl文件,而且在使用到這個對象的aidl文件中聲名它爲Parcelable類型
parcelable User;
複製代碼
aidl文件中每一個實現Parcelable接口的類都須要聲名parcelable,以外除了基本數據類型,其餘類型參數必須標上方向:in out inout
interface IBookManager{
void addBook(in Book book);
}
複製代碼
aidl接口只支持方法,不支持聲明靜態常量
aidl的包結構在服務端和客戶端要保持一直.由於客戶端須要反序列化服務端中和aidl接口相關的全部類,類的完整路徑不同反序列化失敗
aidl方法是在服務端的Binder線程池中執行,CopyOnWriteArrayList自動線程同步,還有ConcurrentHashMap
RemoteCallbackList,自動線程同步,進程終止時自動移除註冊的listener;beginBroadcast()和finishBroadcast()必須配對使用
服務端aidl接口方法所有運行在Binder線程池中,接口方法能夠作耗時操做,若是調用接口的客戶端是在UI線程中,那麼不要再接口方法中作耗時操做不然就會致使ANR;若是明確知道必須作耗時操做,那麼在調用接口的客戶端中須要開啓線程來調用耗時的aidl接口方法
客戶端中的aidl接口運行在客戶端的線程池中,不能作刷新UI;
服務端在UI線程中(好比在onBind方法中獲取客戶端的相關信息)調用客戶端耗時的aidl接口,會致使服務端ANR
客戶端的onServiceConnected()和onServiceDisconnected()運行在UI線程
private IBinder.DeathRecipient recipient = new IBinder.DeathRecipient(){
@override
public void binderDied(){
if(iBookManager == null){
return;
}
iBookManager.asBinder().unlinkToDeath(recipient,0);
iBookManager = null;
//這裏從新綁定遠程Service
}
};
複製代碼
其次,在客戶端綁定遠程服務成功以後,給Binder設置死亡代理
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
iBookManager = IBookManager.Stub.asInterface(binder);
binder.linkToDeath(recipient,0);
}
複製代碼
//authority與表名關聯,根據傳入的URI取出來外界想要操做哪張表
//content://com.icbc.im.provider/user
//content://com.icbc.im.provider/book
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(authority, path, code);
uriMatcher.addURI(authority, path, code);
複製代碼
getContext().getContentResolver().notifyChange(uri, null);
複製代碼
外界註冊數據改變監聽
getContext().getContentResolver().registerContentObserver(uri,true,new ContentObserver(null) {
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
}
});
//解除註冊
getContext().getContentResolver().unregisterContentObserver()複製代碼