1. 程式人生 > >Android IPC程序間通訊(二)Messenger

Android IPC程序間通訊(二)Messenger

Messenger實現程序間低併發即時通訊

Messenger是一種輕量級的IPC,底層實現是AIDL,即可認為Binder。通過在Message中攜帶Bundle進而實現程序之間傳遞資料。由於Messenger一次只能處理一個請求,因此服務端們不用考慮執行緒同步問題。
一,我們在服務端建立一個Handler用於接受來自客戶端訊息,並以此Handler建立Messenger,我們將這個Messenger的Binder物件通過onBinde( )方法返回給客戶端;在客戶端連結服務的onServiceConnected( )方法中取得Binder物件,轉化為Messenger,即可傳送訊息給服務端。
二,我們在客戶端建立一個Handler用於接受來自服務端的訊息,同樣需要以此Handler建立一個Messenger並將它返回給服務端用於傳送訊息,怎麼返回的呢?在客戶端連結服務的onServiceConnected( )方法中,當客戶端向服務端傳送訊息時攜帶上剛剛建立的Messenger物件,message.replyTo = 剛剛建立的Messenger物件,而在服務端的Handler中我們可以從msg中取出來自客戶端的訊息和Messenger物件,Messenger reply = msg.replyTo;以此向客戶端傳送訊息。
三,優點:功能一般,支援一對多序列通訊,支援實時通訊
缺點:不能很好處理高併發,不支援遠端RPC,只能傳輸Bundle支援的資料型別。
適用場景:低併發一對多即時通訊,無RPC請求,或者無需返回結果的RPC請求。
1.服務端

public class MessengerService extends Service {

    public static final int SERVICE_REPLY_WHAT = 100;
    public static final String SERVICE_REPLY_KEY = "service_reply_key";
	//將此Messenger物件傳遞給客戶端,以此向服務端傳送訊息
    private Messenger mMessenger = new Messenger(new ServiceHandler());

    public MessengerService
() { } private class ServiceHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { //收到來自客戶端的指令並進行回覆 case MainActivity.MAIN_SEND_WHAT: String msgStr =
msg.getData().getString(MainActivity.MAIN_SEND_KEY); Toast.makeText(MessengerService.this, msgStr, Toast.LENGTH_SHORT).show(); //取出來自客戶端的Messemger物件,以此想客戶端傳送訊息 Messenger reply = msg.replyTo; Message message = Message.obtain(null, SERVICE_REPLY_WHAT); Bundle bundle = new Bundle(); bundle.putString(SERVICE_REPLY_KEY, "收到來自客戶端訊息,服務端很高興,這是回信。"); message.setData(bundle); try { reply.send(message); } catch (RemoteException e) { e.printStackTrace(); } break; default: super.handleMessage(msg); } } } @Override public IBinder onBind(Intent intent) { //將服務端Handler構造的Messenger的Binger物件傳送給客戶端 return mMessenger.getBinder(); } }

2.客戶端

public class MainActivity extends AppCompatActivity {

    public static final int MAIN_SEND_WHAT = 101;
    public static final String  MAIN_SEND_KEY = "main_send_key";
    //用來自service的IBinder物件構造Messenger,向Service端傳送訊息
    private Messenger mMessenger;
    //以客戶端Handler構造Messenger並傳遞給服務端,服務端以此向客戶端傳送訊息
    private Messenger mSendMessenger = new Messenger(new mainHandler());

    private class mainHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                //收到來自服務端的回信
                case MessengerService.SERVICE_REPLY_WHAT:
                    String msgStr = msg.getData().getString(MessengerService.SERVICE_REPLY_KEY);
                    Toast.makeText(MainActivity.this, msgStr, Toast.LENGTH_SHORT).show();
                default:
                    super.handleMessage(msg);
                    break;
            }

        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,MessengerService.class);
        //繫結服務
        bindService(intent,mConnection,BIND_AUTO_CREATE);
    }
	//服務連線
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder Binder) {
            //取出來自服務端的Binder物件構建Messenger,以此向服務端傳送訊息
            mMessenger = new Messenger(Binder);
            Message message = Message.obtain(null,MAIN_SEND_WHAT);
            Bundle bundle = new Bundle();
            bundle.putString(MAIN_SEND_KEY,"你好Service,這是來自客戶端的問候。");
            message.setData(bundle);
            //將客戶端Handler構造的Messenger傳給服務端,服務端以此Messenger向客戶端傳送訊息
            message.replyTo = mSendMessenger;
            try {
                mMessenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };
}