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:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值