热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Messenger实现进程间的相互通信

通过Messenger可以在不同进程之间通过传递Message对象实现进程间数据的传递;Messenger是一种轻量级的IPC方案,低层使用AIDL实现。由于Messenger一次处理

通过Messenger可以在不同进程之间通过传递Message对象实现进程间数据的传递;Messenger是一种轻量级的IPC方案,低层使用AIDL实现。由于Messenger一次处理一个请求,因此在不存在并发执行的情况下,不再考虑线程同步问题。
下面我们来看具体的实现
我们这里首先在一个应用中创建不同的两个进程,创建MessengerActivity与MessengerService这两个处于不同进程的类,在MessengerService注册时指定它所对应的进程

<activity android:name="com.example.ipcstudy.MessengerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<service android:name="com.example.ipcstudy.MessengerService"
android:process=":MessengerService"/>
"

android:process=”:MessengerService” 指定MessengerService在com.example.ipcstudy:MessengerService进程中;MessengerActivity默认在com.example.ipcstudy进程中。

MessengerService类的实现:

package com.example.ipcstudy;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.widget.Toast;

public class MessengerService extends Service{
//创建Handler用于MessengerActivity中传递的Message对象
private Handler messengerHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MessengerActivity.MESSENGER:
//获取信息内容并Toast
Toast.makeText(MessengerService.this, msg.getData().getString("content"), 0).show();
//获取MessengerActivity中replyMessenger对象
Messenger messenger=msg.replyTo;
//创建传递的消息对象
Message replyMessage=Message.obtain(null, MessengerActivity.MESSENGER);
Bundle bundle=new Bundle();
bundle.putString("reply", "我已经收到消息!");
replyMessage.setData(bundle);
try {
//给MessengerActivity发送消息
messenger.send(replyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
};
};
private Messenger messenger=new Messenger(messengerHandler);
@Override
public IBinder onBind(Intent intent) {
//返回IBinder对象
return messenger.getBinder();
}

}

MessengerActivity类的实现

package com.example.ipcstudy;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.widget.Toast;

public class MessengerActivity extends Activity{
public static final int MESSENGER=111;
private ServiceConnection cOnn=new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//通过服务返回的IBinder对象创建Messenger对象
Messenger messenger=new Messenger(service);
//创建Message对象
Message message=new Message();
message.what=MESSENGER;
Bundle bundle=new Bundle();
bundle.putString("content", "通过Messenger进行跨进程通信");
message.setData(bundle);
//将接收消息的replyMessenger传递给MessengerService
message.replyTo=replyMessenger;
try {
//向MessengerService发送消息
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
/**
* 用于接收MessengerService传递过来的数据Message对象
*/

private Messenger replyMessenger=new Messenger(new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSENGER:
//获取信息内容并Toast
Toast.makeText(MessengerActivity.this, msg.getData().getString("reply"), 0).show();
break;
default:
break;
}
};
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//绑定服务
Intent intent=new Intent(this,MessengerService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
}

注意:
Messenger中进行数据传递必须将数据放入Message中,而Messenger与Message都实现了Parcelable接口,因此可以跨进程传输。
Message只能使用what,arg1,arg2,Bundle,replyto传递信息,Message中object字段仅支持系统提供的实现了Parcelable接口的对象传递信息,我们自己定义Parcelable对象不能进行传输。


推荐阅读
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 探讨 HDU 1536 题目,即 S-Nim 游戏的博弈策略。通过 SG 函数分析游戏胜负的关键,并介绍如何编程实现解决方案。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • 本文介绍如何在Spring Boot项目中集成Redis,并通过具体案例展示其配置和使用方法。包括添加依赖、配置连接信息、自定义序列化方式以及实现仓储接口。 ... [详细]
  • 本题要求实现一个函数,用于检查给定的字符串是否为回文。回文是指正向和反向读取都相同的字符串。例如,“XYZYX”和“xyzzyx”都是回文。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • Spring Boot单元测试中Redis连接失败的解决方案
    本文探讨了在Spring Boot项目中进行单元测试时遇到Redis连接问题的原因及解决方法,详细分析了配置文件加载路径不当导致的问题,并提供了有效的解决方案。 ... [详细]
  • Java 实现二维极点算法
    本文介绍了一种使用 Java 编程语言实现的二维极点算法。该算法用于从一组二维坐标中筛选出极点,适用于需要处理几何图形和空间数据的应用场景。文章不仅详细解释了算法的工作原理,还提供了完整的代码示例。 ... [详细]
  • 本文介绍了如何使用JavaScript的Fetch API与Express服务器进行交互,涵盖了GET、POST、PUT和DELETE请求的实现,并展示了如何处理JSON响应。 ... [详细]
  • 本文详细探讨了Android Activity中View的绘制流程和动画机制,包括Activity的生命周期、View的测量、布局和绘制过程以及动画对View的影响。通过实验验证,澄清了一些常见的误解,并提供了代码示例和执行结果。 ... [详细]
author-avatar
主持人谷佳霓期_426
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有