欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 运维知识 > android >内容正文

android

messenger android 4.,androidipc机制(4)-凯发k8官方网

发布时间:2024/10/14 android 39 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 messenger android 4.,androidipc机制(4)-messenger 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一、概述

除了使用 aidl 进行 ipc 外,我们还可以使用 messenger 来替代 aidl。通过在 message 对象中放入需要传递的对象,利用 messenger 在不同进程间传递 message 对象,就可以方便地进行进程间通信了

messenger 是一种轻量级的 ipc 方案,底层实现依然是 aidl,通过 messenger 的两个构造方法就可以看出来

public messenger(handler target) {

mtarget = target.getimessenger();

}

public messenger(ibinder target) {

mtarget = imessenger.stub.asinterface(target);

}

messenger 对 aidl 进行了封装,使开发者可以更简单地进行进程间通信。此外,由于 messenger 一次只处理一个请求,不会出现并发执行的问题,因此在服务端不用考虑进行线程同步

这里通过 messenger 来实现一个简单的进程间通信,客户端发送一个整数给服务端,服务端再把这个数值打印出来

二、服务端

与 aidl 一样,服务端也要创建一个 service 来处理客户端的连接请求,但服务端的代码要简单得多

首先,通过一个 handler 对象来创建 messenger 对象,然后在 onbind 方法中返回 messenger 对象底层的 binder 即可

/**

* 作者:叶应是叶

* 时间:2018/3/22 20:13

* 描述:https://github.com/leavesc

*/

public class messengerservice extends service {

private static final string tag = "messengerservice";

private static final int code_message = 1;

private static class messengerhandler extends handler {

@override

public void handlemessage(message msg) {

switch (msg.what) {

case code_message: {

log.e(tag, "服务端收到了消息:" msg.arg1);

break;

}

}

}

}

private messenger messenger = new messenger(new messengerhandler());

public messengerservice() {

}

@override

public ibinder onbind(intent intent) {

return messenger.getbinder();

}

}

三、客户端

客户端首先要绑定服务端的 service,绑定成功后通过 serviceconnection 对象的 onserviceconnected 方法的参数 ibinder 来构造一个 messenger 对象,之后通过 messenger 对象即可向服务端发送消息了

/**

* 作者:叶应是叶

* 时间:2018/3/22 20:13

* 描述:https://github.com/leavesc

*/

public class mainactivity extends appcompatactivity {

private static final string tag = "mainactivity";

private static final int code_message = 1;

private messenger messenger;

private serviceconnection serviceconnection = new serviceconnection() {

@override

public void onserviceconnected(componentname name, ibinder service) {

messenger = new messenger(service);

}

@override

public void onservicedisconnected(componentname name) {

messenger = null;

}

};

private edittext et_message;

@override

protected void oncreate(bundle savedinstancestate) {

super.oncreate(savedinstancestate);

setcontentview(r.layout.activity_main);

bindservice();

initview();

}

@override

protected void ondestroy() {

super.ondestroy();

unbindservice(serviceconnection);

}

private void bindservice() {

intent intent = new intent();

intent.setclassname("com.czy.messenger_server", "com.czy.messenger_server.messengerservice");

bindservice(intent, serviceconnection, context.bind_auto_create);

}

private void initview() {

et_message = findviewbyid(r.id.et_message);

button btn_sendmessage = findviewbyid(r.id.btn_sendmessage);

btn_sendmessage.setonclicklistener(new view.onclicklistener() {

@override

public void onclick(view v) {

if (messenger == null) {

return;

}

string content = et_message.gettext().tostring();

if (textutils.isempty(content)) {

return;

}

int arg1 = integer.valueof(content);

message message = new message();

message.what = code_message;

message.arg1 = arg1;

try {

messenger.send(message);

log.e(tag, "消息发送成功");

} catch (remoteexception e) {

e.printstacktrace();

}

}

});

}

}

运行结果如下所示

在上面的示例代码中我是用 message 来承载需要发送的消息的,因为 messenger 和 message 都实现了 parcelable 接口,所以可以跨进程传输。message 中能用来承载数据的载体有 what、arg1、arg2、obj、bundle、replyto。当中,obj 字段在跨进程通信中只能用来承载系统提供的实现了 parcelable 接口的对象,例如 bundle 和 intent。如果承载了非法数据(例如 string),则会发生运行时异常

四、双向通信

以上的例子只是实现了单向通信,还要考虑下如何实现双向通信,即服务端如何向客户端反馈数据?这就需要客户端也需要通过 handler 创建一个 messenger 对象,并将该 messenger 对象通过 message 的 replyto 参数传递给服务端,服务端取得该参数就可以回应客户端了

这里就直接修改上述 ipc 流程,将客户端发给服务端的 arg1 参数乘以 2 后再返回给客户端

首先修改服务端代码

private static class messengerhandler extends handler {

@override

public void handlemessage(message msg) {

switch (msg.what) {

case code_message: {

log.e(tag, "服务端收到了消息:" msg.arg1 " " ((intent) msg.obj).getaction());

//取得客户端的 messenger 对象

messenger messenger = msg.replyto;

message message = new message();

message.what = code_message;

message.arg1 = 2 * msg.arg1;

try {

messenger.send(message);

log.e(tag, "服务端回复消息成功");

} catch (remoteexception e) {

e.printstacktrace();

}

break;

}

}

}

}

为了接收服务端的回复,客户端也需要通过 handler 创建一个 messenger 对象,并将该 messenger 对象通过 message 的 replyto 参数传递给服务端

private messenger replymessenger;

private static class messengerhandler extends handler {

@override

public void handlemessage(message msg) {

switch (msg.what) {

case code_message: {

log.e(tag, "客户端收到了服务端回复的消息:" msg.arg1);

break;

}

}

}

}

btn_sendmessage.setonclicklistener(new view.onclicklistener() {

@override

public void onclick(view v) {

if (messenger == null) {

return;

}

string content = et_message.gettext().tostring();

if (textutils.isempty(content)) {

return;

}

int arg1 = integer.valueof(content);

intent intent = new intent("action");

message message = new message();

message.what = code_message;

message.arg1 = arg1;

message.obj = intent;

//双向通信时需要加上这一句

message.replyto = replymessenger;

try {

messenger.send(message);

log.e(tag, "消息发送成功");

} catch (remoteexception e) {

e.printstacktrace();

}

}

});

运行结果如下所示

从以上介绍可以看出来,messenger 的使用要比 aidl 简单得多,因为 messenger 对 aidl 进行了封装,使之更加容易使用。但需要注意的是,messenger 是以串行的方式处理客户端发送的消息,即使有大量的消息同时到达服务端,服务端也只能一个个处理,所以 messenger 不适合用于处理大量的并发请求,此时就还是需要考虑使用 aidl 了,因为 aidl 支持并发通信

这里提供本系列文章所有的 ipc 示例代码:ipcsamples

总结

以上是凯发k8官方网为你收集整理的messenger android 4.,androidipc机制(4)-messenger的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

网站地图