Android進程通信之Messenger簡單分析和使用

前言—— 生活依舊如此美好   秋不白

        之前有次面試遇到這樣一個問題。如何使用Handler完成Activity和Service間通信?可惜之前對這方面沒有進一步去了解,沒有回答好。

        當然是使用Messenger,查看Messenger的構造方法有兩個,分別是:

  public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }

  public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
    

答案就很明顯了,使用Messenger。

服務中以Messenger(Handler target)來創建信使,在onBind方法中返回IBinder對象

Activity中以bindService來綁定Service,在onServiceConnected()中獲取Service 的IBinder,創建Messenger對象,於是這個信使就持有了Service中的Handler,就可以在Activity中發送消息給Service了,並且在Message的replyTo屬性上可以賦值Messenger對象,Activity和Service通過Messenger完成互相通信,分析就到這裏,再往下我也不懂了,也沒有太大的必要。

通過Messenger的第一個構造方法,也可以看出,底層實現是AIDL,Messenger對AIDL做了封裝,侷限性:一次處理一個請求,如果有大量消息同時發送到服務端,還是得使用AIDL。

插入部分Activity和Service的代碼:

Activity(客戶端):

 public void openIPC(View view) {
        Intent intent = new Intent(this,MyService.class);
        bindService(intent,conn, Context.BIND_AUTO_CREATE);

    }
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Messenger messenger = new Messenger(service);
            Message msg = Message.obtain();
            msg.what = 1;
            Bundle bundle = new Bundle();
            bundle.putString("data","服務端你好,我是客戶端");
            msg.setData(bundle);
            msg.replyTo = new Messenger(new ClientHandler());
            try {
                messenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    private static class ClientHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.d("MainActivity"," 收到服務端發送的消息 " + msg.getData().getString("data"));
        }
    }

Service(服務端):

  public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mMessenger.getBinder();
    }

    private static class MyHandlre extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    Messenger client = msg.replyTo;
                    Log.d("MyService"," 收到客戶端發送的消息 " + msg.getData().getString("data"));
                    Message msgService = Message.obtain();
                    Bundle bundle = new Bundle();
                    bundle.putString("data"," Hi. 客戶端你好,我是服務端");
                    msgService.setData(bundle);
                    try {
                        client.send(msgService);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                case 2:
                    break;
                default:
                    break;
            }

        }
    }
    private final Messenger mMessenger = new Messenger(new MyHandlre());

別忘了在清單文件中給Service指定進程,開啓多進程,更好的體現Messenger進程間通信。分析就到這裏,可以去看看Handler 源碼,AIDL。生活依舊如此美好,一起加油!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章