1. 程式人生 > >Android Messenger跨程序通訊

Android Messenger跨程序通訊

1、目的

實現不同程序間的通訊。可以將客戶端的資料通過Message傳遞到服務端,同時服務端的資料也可以通過Message返回到客戶端。

2、原理

不同程序間的通訊通過Messenger為服務端建立介面,客戶端就可以Message傳送給服務端,交給服務端的Handler進行處理訊息;當然客戶端也可以定義Messenger,方便服務端將處理完的訊息返回給客戶端。

在單一執行緒中建立包含所有請求的佇列,採用序列的方式來處理客戶端傳送來的訊息。

侷限性:不能處理大量併發請求。因為所有的請求都是序列執行

3、使用過程

(1)客戶端傳送message到服務端

建立一個類繼承於Service

(a)伺服器實現一個Handler,來接收客戶端的訊息


    private class MessengerHandler  extends Handler{
        @Override
        public void handleMessage(Message msg) {
            Log.d("MessService","Message is from client");
    
        }
    }

(b)通過上面建立的Handler來建立Messenger物件

  private Messenger messenger = new Messenger(new MessengerHandler());

(c)將上述的Messenger建立IBinder,通過onBinder返回給客戶端

    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }

在Acitivity中實現bind該service 

(e)客戶端bind該service

  private ServiceConnection messConnect = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
             isBinderService = true;
            servermessenger = new Messenger(service);
            Log.d("MessService","bind success");
            Message msg = Message.obtain();
            msg.what = 1;
            msg.arg1 = 2;
            try {
                servermessenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBinderService = false;
            servermessenger = null;
        }
    };
    private void startMessService(){
        if (isBinderService){
            return;
        }
        isBinderService= bindService(new Intent(MainActivity.this, MessService.class),messConnect,Context.BIND_AUTO_CREATE);
    }

(f)在AndroidMenifest檔案中註冊該服務,這裡將該Service放到另外一個程序中


        <service android:name=".service.MessService"
            android:process=".messservice">
        </service>

 上述幾步就可以實現了將Message傳送到服務端,列印日誌如下:

10-30 14:30:57.261 6094-6094/com.j1 D/MessService: bind success
10-30 14:30:57.262 6137-6137/? D/MessService: Message is from client

(2)服務端回撥message到客戶端

在Activity中

(a)在客戶端中定義自己的Messenger

    private Messenger clientMessenger = new Messenger(new Handler(){
        @Override
        public void handleMessage(Message msg) {
            Log.d("MessService","get msg from server"+msg.what+", "+msg.arg1);
        }
    });

(b)將該定義的Messenger和傳送給服務端的Message繫結到一起,可以在服務端接收到Message的時候,獲得該Messenger,方便伺服器回傳Message。

在上面的(e)中建立的Message中繫結該Messenger

//。。。。省略程式碼            
            Message msg = Message.obtain();
            msg.what = 1;
            msg.arg1 = 2;
            msg.replyTo = clientMessenger;
//。。。。省略程式碼 

在自定義的Service中

(c)在服務端需要返回Message的地方獲取(a)建立的Messenger來回傳訊息。我們暫時先放到Handler

        @Override
        public void handleMessage(Message msg) { 
//。。。。省略程式碼        
            Messenger clientMessenger = msg.replyTo;
            try {
                clientMessenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
//。。。。省略程式碼
        }

上述幾步就可以完成,服務端將Message返回給客戶端,列印日誌如下:

10-30 15:16:12.290 7944-7944/com.j1 D/MessService: get msg from server

4、總結

(1)Messenger對AIDL進行封裝,可以實現基於訊息的跨程序通訊。

(2)客戶端和服務端都可以Messenger來傳遞訊息,通過msg.repayTo = clientMessenger來將客戶端的Messenger傳遞給服務端。

(3)