(原创)使用Messenger进行轻量级跨进程通信
安卓跨进程通信方式在安卓开发中其实有六大跨进程通信方式有的是我们经常用的有的用得少。分别是1.AIDL最常用、功能最强2.Binder底层核心所有 IPC 的底层都是 Binder3.ContentProvider专门给别的 APP 读数据4. BroadcastReceiver 广播5. Socket网络套接字6. Messenger最简单、轻量、基于 Handler、串行、单线程Messenger如何实现跨进程通信Messenger其实是通过handler来通信的因为handler是一条一条消息发过来并处理。所以是串行的下面从客户端和服务端分别介绍如何通信服务端服务端一般是一个service需要创建一个信使也就是MessengerprivatevalserviceMessengerMessenger(serviceHandler)在onbind方法中把这个信使的binder返回回去overridefunonBind(intent:Intent):IBinder{returnserviceMessenger.binder}方便客户端使用信使的创建的时候构造方法里面需要一个handler这个handler就是用来接收并且处理另外一端发来的消息具体代码下面源码都有客户端一样的客户端也需要一个客户端的信使和自己用来处理消息的handlerprivatevalclientMessengerMessenger(clientHandler)在绑定服务端的service中可以拿到服务端的信使overridefunonServiceConnected(name:ComponentName,service:IBinder){// 绑定成功获取服务端信使serverMessengerMessenger(service)isBindtrueToast.makeText(thisMainActivity,绑定远程服务成功,Toast.LENGTH_SHORT).show()}这样客户端就可以用服务端的信使发消息给服务端// 发送消息到远程服务// 点击按钮发送消息funsendMsg(view:View?){if(!isBind||serverMessengernull)returntry{valmsgMessage.obtain(null,1001)valbundleBundle()bundle.putString(obj_client,你好服务端)msg.databundle// msg.obj 你好服务端 //不可以用obj进行跨进程传递对象数据哪怕是string系统会认为数据没有序列化然后报错// 携带自己的信使让服务端可以回复msg.replyToclientMessenger// 发送消息到远程服务serverMessenger!!.send(msg)}catch(e:RemoteException){e.printStackTrace()}}发送的时候客户端通过replyTo 字段把自己端的信使传递给服务端这样服务端拿到客户端的信使就可以发消息给客户端msg.replyToclientMessenger相当于两端都各自拿到对面的信使就可以进行通信最后如果要解绑服务记得释放服务端的信使避免内存泄漏serverMessengernull页面退出也记得移除handler的消息// 清空Handler防泄漏clientHandler.removeCallbacksAndMessages(null);Messenger对比AIDL相同点1.都与IPC的调用有关2.Messenger 是一种轻量级的 IPC方案底层实现了AIDL只是进行了封装开发的时候不用再写.aidl文件。3.都支持实时通信不同点1.Messenger一次只能处理一个请求串行/AIDL一次可以处理多个请求并行2.Messenger不支持RPC只能通过message传递消息/AIDL支持RPC3.Messenger使用简单轻量级不需要创建AIDL文件/AIDL使用复杂需要创建AIDL文件源码Activityimportandroid.content.ComponentNameimportandroid.content.Intentimportandroid.content.ServiceConnectionimportandroid.os.Bundleimportandroid.os.Handlerimportandroid.os.IBinderimportandroid.os.Looperimportandroid.os.Messageimportandroid.os.Messengerimportandroid.os.RemoteExceptionimportandroid.view.Viewimportandroid.widget.Toastimportandroidx.activity.enableEdgeToEdgeimportandroidx.appcompat.app.AppCompatActivityimportandroidx.core.view.ViewCompatimportandroidx.core.view.WindowInsetsCompatclassMainActivity:AppCompatActivity(){// 客户端Handler接收并处理服务端回复privatevalclientHandler:Handlerobject:Handler(Looper.getMainLooper()){overridefunhandleMessage(msg:Message){super.handleMessage(msg)if(msg.what2001){valbundlemsg.datavalresultbundle.getString(obj_server)Toast.makeText(thisMainActivity,客户端收到回复$result,Toast.LENGTH_SHORT).show()}}}// 服务端信使用于发送消息给服务端privatevarserverMessenger:Messenger?null// new Messenger(clientHandler) 把客户端Handler包装成信使用于接收服务端消息privatevalclientMessengerMessenger(clientHandler)//绑定状态privatevarisBindfalse// 服务连接privatevalconnection:ServiceConnectionobject:ServiceConnection{overridefunonServiceConnected(name:ComponentName,service:IBinder){// 绑定成功获取服务端信使serverMessengerMessenger(service)isBindtrueToast.makeText(thisMainActivity,绑定远程服务成功,Toast.LENGTH_SHORT).show()}overridefunonServiceDisconnected(name:ComponentName){Toast.makeText(thisMainActivity,取消绑定远程服务成功,Toast.LENGTH_SHORT).show()isBindfalseserverMessengernull}}overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)enableEdgeToEdge()setContentView(R.layout.activity_main)ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)){v,insets-valsystemBarsinsets.getInsets(WindowInsetsCompat.Type.systemBars())v.setPadding(systemBars.left,systemBars.top,systemBars.right,systemBars.bottom)insets}// 绑定服务bindService()}// 绑定服务privatefunbindService(){valintentIntent(this,RemoteService::class.java)bindService(intent,connection,BIND_AUTO_CREATE)}// 点击按钮发送消息funsendMsg(view:View?){if(!isBind||serverMessengernull)returntry{valmsgMessage.obtain(null,1001)valbundleBundle()bundle.putString(obj_client,你好服务端)msg.databundle// msg.obj 你好服务端 //不可以用obj进行跨进程传递对象数据哪怕是string系统会认为数据没有序列化然后报错// 携带自己的信使让服务端可以回复msg.replyToclientMessenger// 发送消息到远程服务serverMessenger!!.send(msg)}catch(e:RemoteException){e.printStackTrace()}}overridefunonDestroy(){super.onDestroy()// 解绑服务if(isBind){unbindService(connection)isBindfalse}// 清空Handler防泄漏clientHandler.removeCallbacksAndMessages(null);}}Serviceimportandroid.app.Serviceimportandroid.content.Intentimportandroid.os.Bundleimportandroid.os.Handlerimportandroid.os.IBinderimportandroid.os.Looperimportandroid.os.Messageimportandroid.os.Messengerimportandroid.os.RemoteExceptionimportandroid.widget.ToastclassRemoteService:Service(){privatevalserviceHandlerHandler(Looper.getMainLooper()){msg-//客户端信使valclientMessengermsg.replyTovalbundlemsg.datavalcontentbundle.getString(obj_client)when(msg.what){1001-{Toast.makeText(thisRemoteService,服务端收到$content,Toast.LENGTH_SHORT).show()try{valreplyMsgMessage.obtain(null,2001)valbundleBundle()bundle.putString(obj_server,服务端已收到已处理完毕)replyMsg.databundle// msg.obj 服务端已收到已处理完毕 //不可以用obj进行跨进程传递对象数据哪怕是string系统会认为数据没有序列化然后报错clientMessenger.send(replyMsg)}catch(e:RemoteException){e.printStackTrace()}}}true}//服务端信使privatevalserviceMessengerMessenger(serviceHandler)overridefunonBind(intent:Intent):IBinder{returnserviceMessenger.binder}}xml里面写个button就可以?xml version1.0encodingutf-8?androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:idid/mainandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.MainActivityButtonandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClicksendMsgandroid:textHello World!app:layout_constraintBottom_toBottomOfparentapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparent//androidx.constraintlayout.widget.ConstraintLayout最后记得配置清单注册!--远程服务单独进程--serviceandroid:name.RemoteServiceandroid:process:remote/

相关新闻

单片机IO口扩展方案与74HC595/165应用详解

单片机IO口扩展方案与74HC595/165应用详解

1. 为什么需要IO口扩展?在单片机开发中,IO口资源紧张是工程师们经常遇到的痛点。以常见的51单片机为例,标准型号通常只有32个IO口,而实际项目中往往需要控制数十个LED、多个按键输入、各种传感器接口等。当IO口数量不足时&#xf…

2026/7/31 7:27:38 阅读更多 →
Android内存溢出(OOM)问题解析与优化实践

Android内存溢出(OOM)问题解析与优化实践

1. Android内存溢出问题概述在Android开发中,内存溢出(OutOfMemoryError)是最常见的性能问题之一。当应用尝试分配超过系统限制的内存时,就会抛出这个错误。作为一名有五年Android开发经验的工程师,我处理过各种OOM问题,从简单的图…

2026/7/30 19:31:52 阅读更多 →
嵌入式机械臂智能售卖系统:从运动控制到多传感器融合实战

嵌入式机械臂智能售卖系统:从运动控制到多传感器融合实战

如果你正在参加嵌入式比赛,或者对智能硬件开发感兴趣,可能会发现一个现象:很多参赛作品要么停留在简单的传感器数据采集,要么就是功能单一的控制系统。但真正能让人眼前一亮的作品,往往是把嵌入式技术应用到真实生活场…

2026/7/30 19:12:31 阅读更多 →

最新新闻

使用大疆TSDK提取热红外图像(RJPG)温度信息,热红外图像转tiff或tif,并使用pix4d将tiff或tif进行拼接 | 热红外照片温度信息提取,可处理1280x1024图像大小(重制版二)

使用大疆TSDK提取热红外图像(RJPG)温度信息,热红外图像转tiff或tif,并使用pix4d将tiff或tif进行拼接 | 热红外照片温度信息提取,可处理1280x1024图像大小(重制版二)

看到很多人在处理热红外图像的时候会遇到两个问题,一个是在代码中调整四个参数然后再arcmap中打开查看太费时间和精力了,还有一个是代码只能处理640x512大小的热红外图像,处理1280x1024大小的热红外图像会报错。这次的重置版主要解决这两个问…

2026/7/31 18:54:29 阅读更多 →
银河麒麟V10硬件信息排查:dmidecode/lshw/lsscsi常用命令手册

银河麒麟V10硬件信息排查:dmidecode/lshw/lsscsi常用命令手册

查询硬件信息硬件关系图谱Windowslinux查看cpu信息lscpufreedmidecode命令(硬件)所有参数biossystembaseboard(主板)chassis()processor(处理器)网卡网卡硬件信息查看所有网络接口查看网口详细信息lspci硬件关系图谱 #mermaid-svg-VA7dGFSnQSy0GWkF{font…

2026/7/31 18:54:29 阅读更多 →
环境变量排查:$PATH、/etc/profile与systemd环境冲突解决

环境变量排查:$PATH、/etc/profile与systemd环境冲突解决

银河麒麟V10环境变量排查:$PATH、/etc/profile与systemd环境冲突解决 适用场景:在麒麟 V10 上部署软件时,经常遇到「我在终端能跑,放进 systemd 服务就找不到命令/变量」——本质是登录 shell、环境文件与 systemd 的 environment 加载顺序不一致。本文一次讲清排查路径。 …

2026/7/31 18:54:28 阅读更多 →
一键关闭禁用Windows11/10自动更新实用工具,免费全版本通用!!!

一键关闭禁用Windows11/10自动更新实用工具,免费全版本通用!!!

黄拖鞋自动更新关闭工具你肯定遇到过这种崩溃瞬间:正在赶deadline,系统突然弹出“正在配置更新”;或者早上开机准备开会,却对着“更新进行中,请勿关闭计算机”的屏幕干等了半小时。Windows的强制自动更新,确…

2026/7/31 18:53:28 阅读更多 →
Android Studio中Compse界面使用LayoutInspector报错

Android Studio中Compse界面使用LayoutInspector报错

最近换了电脑,然后把开发环境重新搭建了一下,基本完成后,连接设备准备看看一个UI布局的问题。我用的是Compose写的界面,当我尝试用LayoutInspector的时候居然报错失败了,界面提示:Could not download andro…

2026/7/31 18:53:28 阅读更多 →
数字孪生案例 | 浮托安装数字孪生:环境复刻、安装预演、虚实同步、VR培训全流程

数字孪生案例 | 浮托安装数字孪生:环境复刻、安装预演、虚实同步、VR培训全流程

2.5万吨,7小时。这是"海风之心"海上柔性直流换流平台的浮托安装记录——用一艘半潜驳船,载着相当于40列高铁重量的上部模块,借潮汐浮力完成海上"挺举",将模块精准对接到导管架顶部的对接腿上。整个过程不能出…

2026/7/31 18:53:28 阅读更多 →

日新闻

物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:34 阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:34 阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:34 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻