Messenger 實現進程間通信IPC

AIDL可以實現進程間通信,但使用稍顯複雜,Messenger也可以實現進程間通信,Messenger底層實現利用了 AIDL ,系統已經幫我們完成了Aidl的書寫。Messenger可以在不同進程中傳遞 Message 對象,利用Handler一次只處理一個請求,不存在併發執行的情形。所以這是Messenger的優點,也是它的缺點,它無法用於大量的併發操作,但對於簡單的進程間通信則十分好用。利用bindService客戶端和服務端可以拿到對方的 Messenger 來發送 Message 的。客戶端通過 bindService onServiceConnected ,服務端通過 message.replyTo 來獲得對方的 Messenger 。

下面的例子,服務器和客戶端是兩個應用。

1 服務器端寫法

定義一個Service,利用自定義handler生成Messenger,然後在onBind中獲取它的binder,client端可以進行

public class MessengerService extends Service {
    private static final String TAG = MessengerService.class.getSimpleName();

	//服務器Messenger
    private Messenger serviceMessenger = new Messenger(new MessengerHandler());

    private class MessengerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 2) {
                System.out.println("===========getDataFromClient=========" + msg.getData().getString("data"));
                //獲取客戶端的Messenger
                Messenger client = msg.replyTo;
                //新建也行
                Message replymsg = Message.obtain(null, 1);
                Bundle bundle = new Bundle();
                bundle.putString("data", "服務器回覆信息");
                //向客戶端發送信息
                replymsg.setData(bundle);
                try {
                    client.send(replymsg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            } else {
                super.handleMessage(msg);
            }
        }
    }

    public MessengerService() {
    }

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

AndroidManifest.xml中聲明,由於需要外部調用(隱式啓動)exported= true,還需要設置action

 <service
            android:name=".service.MessengerService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.ldx.demo.messenger.service" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>

2 客戶端

客戶端通過綁定service,獲取服務器的Messenger,通過服務器Messenger的replyTo指向客戶端的Messenger發送信息。


public class ClientActivity extends AppCompatActivity {

    TextView mStart;
    TextView mSend;
    TextView mData;

    //客戶端messenger
    private Messenger mClientMessenger = new Messenger(new MessageHandler());
    private Messenger mServiceMessenger;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);
        mStart = findViewById(R.id.start_service);
        mSend = findViewById(R.id.send_message);
        mData = findViewById(R.id.get_message);
        initEvent();
    }

    private void initEvent() {
        mStart.setOnClickListener(view -> {
            bindService();
        });

        mSend.setOnClickListener(view -> {
            sendMessage();
        });
    }

    private void bindService(){
        Intent intent = new Intent();
        intent.setAction("com.ldx.demo.messenger.service");
        bindService(intent, mConnection, Service.BIND_AUTO_CREATE);
    }

    private class MessageHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){
                System.out.println("============收到服務器信息=========="+msg.getData().get("data"));
                if (mData != null){
                   String data =  mData.getText().toString();
                   if (data != null){
                       mData.setText(data+"\n"+"服務器發送的消息:"+msg.getData().get("data"));
                   }
                }
            }else{
                super.handleMessage(msg);
            }
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            try {
                //獲取服務器Messenger
                mServiceMessenger = new Messenger(service);
                Message message = Message.obtain(null,2);
                message.replyTo = mClientMessenger;
                mServiceMessenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServiceMessenger = null;
        }
    };

    public void sendMessage() {
       if (mServiceMessenger != null){
           Message msg = Message.obtain(null,2);
           Bundle data = new Bundle();
           data.putString("data", "我是客戶端");
           msg.setData(data);
           msg.replyTo = mClientMessenger;
           try {
               //發送信息
               mServiceMessenger.send(msg);
               if (mData != null){
                   String str =  mData.getText().toString();
                   if (str != null){
                       String str2 = str+"\n"+"client發送的消息:"+"我是客戶端";
                       mData.setText(str2);
                   }
               }
           } catch (RemoteException e) {
               e.printStackTrace();
           }
       }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mConnection);
    }
}

result:
在這裏插入圖片描述

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