Android ipc数据传递方式之二 Messenger 信使

之前ipc数据传递相关文章: ipc数据传递方式之一 aidl


Messenger可以翻译为信使 顾名思义 它可以在不同进程之间传递Message对象,我们在Message中放置我们要传递的数据,就可以进行进程间的数据传递了

看一下Messenger的构造方法 很明显Messenger的底层是由aidl实现的 使用Messenger进行进程间通讯也更加方便

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

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


来一张图理解下Messenger的工作原理



 Messenger的使用

首先创建一个服务并在清单文件中注册以及指定其在新进程中运行

        <service android:name=".MessengerService" android:process=":remote"/>

然后分别创建服务端和客户端

服务端的代码:

public class MessengerService extends Service {
    
    private static final String TAG = "MessengerServic";


    //MessengerHandler继承Handler 用来处理客户端发送过来的message
 private static class MessengerHandler extends Handler {
     @Override
     public void handleMessage(Message msg) {
         switch (msg.what){
             case 1:
                 //打印接收客户端发送过来的消息
                 Log.d(TAG, "msg.getData():" + msg.getData().getString("msg"));
                 
                 //服务端收到消息后向客户端回复 服务端带上replyto参数代表回复
                 //客户端会找到同样标记replyTo参数的Messenger
                 Messenger toclient = msg.replyTo;
                 Message message = Message.obtain(null,2);
                 Bundle bundle = new Bundle();
                 bundle.putString("reply" , "服务端向你回复");
                 message.setData(bundle);
                 try {
                     toclient.send(message);
                 } catch (RemoteException e) {
                     e.printStackTrace();
                 }
                 break;
         }
     }
 }

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

 
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //Messenger.getBinder方法返回一个Binder对象
        return messenger.getBinder();
    }
}

客户端的代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button toservicebtn;

    private Messenger toServermessenger;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //根据服务端返回的ibinder对象创建messenger对象
            toServermessenger = new Messenger(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };


    //客户端接收服务端的回复
    private static class MessengerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 2:
                    //打印服务端的回复
                    Log.d("MessengerHandler", msg.getData().getString("reply"));
                    break;
            }
        }
    }

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


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        //绑定服务
        Intent intent = new Intent(this,MessengerService.class);
        bindService(intent,connection,BIND_AUTO_CREATE);
    }

    private void initView() {
        toservicebtn = (Button) findViewById(R.id.toservicebtn);

        toservicebtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.toservicebtn:
                //客户端向服务端发送消息
                //第二个参数是msgwhat 用作handlermessage回调中的switch判断
                Message msg = Message.obtain(null,1);
                Bundle data = new Bundle();
                data.putString("msg","this is client");
                msg.setData(data);
                //很关键的一点:当客户端发送消息的时候 需要把接收服务端回复的Messenger
                //通过Message的replyTo参数传递给服务端 这样服务端知道回复给谁
                msg.replyTo = getReplyMessenger;
                try {
                    //Messenger信使把message发走
                    toServermessenger.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
        }
    }
}

acticity中有个按钮 在点击事件中向服务端发送消息,每次发送完成之后 服务端会向客户端回复

这样Messenger进程间通讯就完成了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值