欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-12-15 16:17:09
messenger可以翻译为信使 顾名思义 它可以在不同进程之间传递message对象,我们在message中放置我们要传递的数据,就可以进行进程间的数据传递了 看一下messenger的构造方法...

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

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

    public messenger(handler target) {
        mtarget = target.getimessenger();
    }

    public messenger(ibinder target){
        mtarget = imessenger.stud.asinterface(target);
    }

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

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

messenger的使用

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

        

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

服务端的代码:

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进程间通讯就完成了