如何使用Messenger(IPC)

如何使用Messenger(IPC) 如何使用AIDL-非同步實作中, 示範了如何使用aidl來跟兩個不同的Process進行溝通,
其實Android也提供Messenger更簡便的方式來讓你使用。

官網說明

如果您的介面需要跨不同處理程序運作,則可以建立內含 Messenger 服務的介面。
此服務定義了回應不同類型 Message 物件的 Handler。
這個 Handler 是 Messenger 的基礎,之後可以與用戶端分享 IBinder,讓用戶端使用 Message 物件傳送命令給此服務。
此外,用戶端可以定義專屬的 Messenger,服務就可以傳回訊息。
這是處理程序間通訊 (IPC) 最簡單的執行方式,
因為 Messenger 會將所有要求都排列到單一個執行緒,
因此,就不用將服務設計成執行緒安全的形式。

Remote Side

跟AIDL相同, 先宣告Service讓Client進行連結,
Messenger mMessenger = new Messenger(new Handler());
接著可以透過HandlerThread來進行連接
mHandlerThread = new HandlerThread("remote service");
mHandler = new Handler(mHandlerThread.getLooper());
mMessenger = new Messenger(mHandler);
mHandlerThread.start();
連結好Handler之後就可以透過onBind傳送過去。
@Override
public IBinder onBind(Intent intent) {
     return mMessenger.getBinder();
}
記得宣告AndroidMenifest process跟filter
<service
    android:name=".RemoteService"
    android:process=":remote">
    <intent-filter>
        <action android:name="service.remote" />
    </intent-filter>
</service>

Client Side

這邊跟聯繫Service相同, 必須透過ServiceConnection來進行聯繫。
mServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //connection
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        //disconnection
    }
};
接著透過Intent進行Service的聯繫
Intent intent = new Intent();
intent.setAction("service.remote");
intent.setPackage("example.givemepass.messengerremotedemo");
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
而這邊要傳送Task過去其實變得非常簡單
Message m = new Message();
//handle message
messenger.send(m);
跟你平常Handler在處理訊息是一樣的。
這樣就完成IPC了。