IPC簡介
IPC —Inter-Process Communication 含義就是進程間通信,或者跨進程通信
IPC的適用場景以及優缺點
名稱 | 有點 | 缺點 | 適用場景 |
---|---|---|---|
Bundle | 簡單易用 | 只支持傳輸Bundle支持的數據類型 | 四大組件間的進程通信 |
文件共享 | 簡單易用 | 不適合高併發場景,並且無法做到進程間的即是通信 | 無併發訪問情形,交換簡單的數據實時性不高的場景 |
AIDL | 功能強大,支持一對多併發通信,支持實時通信 | 使用稍微複雜,需要處理好線程同步 | 一對多通信且有RPC需求 |
Messenger | 功能一般,支持一對多串行通信,支持實時通信 | 不能很好的處理高併發情形,不支持RPC,數據通過Message進行傳輸,因此只能傳輸Bundle支持的數據類型 | 低併發的一對多即是通信,無RPC需求,或者無須返回結果的RPC需求 |
ContentProvider | 在數據源訪問方面功能強大,支持一對多併發數據共享,可通過Call方法擴展其他操作 | 可以理解爲受約束的AIDL,主要提供數據源的CRUD操作 | 一對多的進程間的數據共享 |
Socket | 功能強大,可以通過網絡傳輸字節流,支持一對多併發實時通信 | 實現細節稍微煩瑣,不支持直接的RPC | 網絡數據交換 |
IPC 基礎概念
Parcelable
Android中使用Parcelable來實現序列化
AndroidStudio中使用插件來實現序列化類, 請移步
Binder
- 從Android FrameWordk層: Binder 是ServiceManager連接各種Manager(ActivityManager, WindowManager, ……)和相應ManagerService的橋樑
- 從Android角度: Binder是客戶端和服務器端進行通信的媒介,當bindService的時候,服務器會返回一個包含了服務器端業務調用的Binder對象,通向這個Binder對象,客戶端可以通過服務器端提供的服務或者數據.
Android中的ICP
1.Bundle
2.文件共享
3.Messenger (信使)
Messenger 對AIDL進行封裝,底層實現還是AIDL.以串行的方式處理客戶端發來的的消息,如果客戶端發來大量的消息,Messenger還是一個個處理. 所以Messenger 在跨進程中最主要的作用就是傳遞消息,故名信使
Messenger所涉及到的就是 Message(消息),通過Handler來發送消息和接受消息.
工作原理
服務器端進程
- 創建一個Service,用來處理客戶的的連接請求. MessengerService extend Service
- 創建一個Handler mHandler = new Handler();
- 使用mHandler 來創建一個Messenger對象, Messenger mMessenger = new Messenger(mHandler);
- Service 的onBind(){ return mMessenger.getBinder();}
客戶端進程
- 綁定服務器端的Service,綁定成功,返回的IBinder對象創建一個Messenger
- 通過這個Messenger向服務器發送消息,類型爲Message
服務器代碼
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
//TODO ① 創建一個Handler
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_CLIENT:
Log.i(TAG, "receive msg from Client:" + msg.getData().getString("msg"));
Messenger client = msg.replyTo;
Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("reply", "嗯,你的消息我已經收到,稍後會回覆你。");
relpyMessage.setData(bundle);
try {
client.send(relpyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
//TODO ② 使用創建的Handler 來創建 Messenger
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Override
public IBinder onBind(Intent intent) {
//TODO ③ 返回Messenger的 Binder
return mMessenger.getBinder();
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}
客戶端代碼
public class MessengerActivity extends Activity {
private static final String TAG = "MessengerActivity";
private Messenger mService;
private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_SERVICE:
Log.i(TAG, "receive msg from Service:" + msg.getData().getString("reply"));
break;
default:
super.handleMessage(msg);
}
}
}
// TODO ① 綁定一個服務
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
//TODO ②使用Ibinder 來創建Messenger
mService = new Messenger(service);
Log.d(TAG, "bind service");
//TODO ③Message 爲傳輸數據
Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg", "hello, this is client.");
msg.setData(data);
msg.replyTo = mGetReplyMessenger;
try {
//TOOD ④ Messenger.send 發送Message 到服務器
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
Intent intent = new Intent("com.ryg.MessengerService.launch");
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}