Android Service--通信方式(IBinder回调、Messenger)

Android中的Service:Binder,Messenger,AIDL(2) 前言前面一篇博文介绍了关于Service的一些基本知识,包括service是什么,怎么创建一个service,创建了一个service之后如何启动它等等。在这一篇博文里有一些需要前一篇铺垫的东西,建议没有看过前一篇博文的同学先去看一下前一篇: Android中的Service:默默的奉献者 (1) 。但是在前一篇博文中也有一些遗漏的东西——主要是关于bindService()这一块的具体细节。由于这 阅读详情

Activity与Service的通信,分两大类,同一个进程中、不同的进程中。

同一个进程中

可以通过直接实现IBinder接口,或者继承Binder类。Binder类是系统提供的一个IBinder接口的实现类。

Service中:

  public class MyBind extends Binder {
        public MyService getService() {
            return MyService.this;
        }
    }

在onBind的时候返回MyBind

@Override
    public IBinder onBind(Intent intent) {
        super.onBind(intent);
        return new MyBind();
    }

Activity中:
bindService的时候在ServiceConnection的回调中得到MyService对象

    conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                isBind = true;
                if (service instanceof MyService.MyBind){
                     myService = ((MyService.MyBind) service).getService();
                }
                Log.i("life", "ServiceConnection-----onServiceConnected");
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                isBind = false;
                Log.i("life", "ServiceConnection----onServiceDisconnected");
            }
        };

这样就在activity中的到了Service的对象。就可以随意调用Service提供的方法了。

不同的进程中

Messenger方式
Messenger需要结合Handler一起使用。有send方法,最终调用的是handler方法。

Service中:

	private MyHandler handler;
    private Messenger messenger;

    @Override
    public void onCreate() {
        super.onCreate();
        handler = new MyHandler();
        messenger=new Messenger(handler);
    }

....
 public static class MyHandler extends Handler {
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);
            Log.i("life", "MyHandler----dispatchMessage");
            Log.i("life", Thread.currentThread().getName());
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.i("life", "MyHandler----handleMessage");
        }
    }

需要一个handler,一个Messenger对象。handler最终会负责发送和接收消息。我们就可以在MyHandler中处理Activity发来的各种消息了。

Activity中:

conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                isBind = true;
                messenger = new Messenger(service);
                Log.i("life", "ServiceConnection-----onServiceConnected");
                Log.i("life", Thread.currentThread().getName());
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                isBind = false;
                Log.i("life", "ServiceConnection----onServiceDisconnected");
            }
        };
        
....
//点击发送
Message message = Message.obtain();
message.what = 5;
try {
	messenger.send(message);
} catch (RemoteException e) {
	e.printStackTrace();
}

这样就完成了通过Messenger夸进程传递内容了。

Messenger源码浅析:

public final class Messenger implements Parcelable {
    private final IMessenger mTarget;

    /**
     *构造方法需要一个handler对象
     *@param target 将接收发送的消息
     */
    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
    
     /**
     * @return 返回当前Messenger的IBinder对象
     */
    public IBinder getBinder() {
    	//其实也是封装了AIDL
        return mTarget.asBinder();
    }
    
    /**
     *构造方法了
     * @param target 需要传入之前通过getBinder()的到的IBinder
     */
    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }
    
    /**
     *发送消息
     *如果handler已经不存在了,抛异常
     */
    public void send(Message message) throws RemoteException {
        mTarget.send(message);
    }

上面四个方法就是我们调用的,前面两个方法在Service中调用。后两个方法在Activity中调用。
类中有一个对象 private final IMessenger mTarget,在传入Handler对象的时候进行的实例化。
看下handler.getIMessenger();

....
	final IMessenger getIMessenger() {
        synchronized (mQueue) {
            if (mMessenger != null) {
                return mMessenger;
            }
            mMessenger = new MessengerImpl();
            return mMessenger;
        }
    }
....
    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            msg.sendingUid = Binder.getCallingUid();
            Handler.this.sendMessage(msg);
        }
    }

可以看到IMessenger 的对象来自handler的内部类MessengerImpl 。而这个类其实是继承了一个AIDL生成的类,AIDL提供了一个send(Message msg) 方法。并且还给这个msg赋值了sendingUid,也就是当前启动Service的应用ID,最终通过handler发送msg。
这样Looper就可以知道这个消息所在的应用和所对应的handler。在列子中,所在的线程在Service的主线程中,而一个线程只有一个Looper

双向通信

上面利用Messenger实现了Activity向Service夸进程发送消息。那如何来实现,Service像Activity发送消息呢。
当然还是要利用Messenger,那么如何传递一个Messenger对象到Service呢,Activity中可没有对应的回调。
来看代码:
Activity中:

//处理接收消息的handler。
public class ActivityHandler extends Handler {
        @Override
        public void dispatchMessage(Message msg) {
            super.dispatchMessage(msg);
            Log.i("life", "ActivityHandler----dispatchMessage");
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.i("life", "ActivityHandler----handleMessage");
            bt2.setText("service来消息啦");
        }
    }
......
	/**
     * Activity中的Messenger对象
     */
    private Messenger activityMessenger;
    /**
     * Activity中接收消息的handler
     */
    private ActivityHandler handler;
 	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        ButterKnife.bind(this);
        ....
        handler = new ActivityHandler();
        activityMessenger = new Messenger(handler);
    }

上面代码完成了Messenger和Handler对象的创建,接下来,把Messenger传递到Service中。

			...
 			case R.id.bt_1:
                Message message = Message.obtain();
                message.what = 5;
                //将Activity中的Messenger对象,交给message对象
                message.replyTo = activityMessenger;
                try {
                	//向Service发送消息
                    serviceMessenger.send(message);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
                ...

Meesage类的变量replyTo就是一个Messenger对象
public final class Message implements Parcelable {
.....
    /**
     * Optional Messenger where replies to this message can be sent.  The
     * semantics of exactly how this is used are up to the sender and
     * receiver.
     */
    public Messenger replyTo;
.....
}

通过上面的代码,把Activity中的Messenger对象,交给了发送过去的Message对象。
Service中的接收并向Activity中发送

 		@Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.i("life", "MyHandler----handleMessage");
            //取出Activity中传递过来的Messenger对象,并发送消息
            Messenger activityMessenger=msg.replyTo;
            try {
            	msg=Message.obtain();
                activityMessenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

上面的代码在Service中完成了接收,和反馈消息。

总结:

  • 同一个进程中,可以使用IBinder子类回调。当然也可以用Messenger。这个时候的Activity和Service运行在同一个线程中。
  • 不同进程,IBinder子类回调不在支持,Messenger是一种方式。这个时候的Activity和Service运行在不同的线程中。
  • 其实Messenger内部实现也是AIDL。

Messenger步骤:

  1. 利用需要handler作为参数的构造方法实例化Messenger对象。
  2. 把Messenger通过某种方式回调到,消息发送方。
    比如:文章中Service中使用onBind回调到Activity中;Activity利用发送的Message来携带到Service中。
  3. 调用Messenger的send方法发送消息。
  4. handler处理消息。

进程之间的内存资源是独立的,那么message对象和Messenger对象,为啥可以传递呢?
没错就是序列化和反序列化。这样传输的数据就转化为能够在内存之间流通的形式了,也就是IO流操作了。Message和Messenger这两个类都是实现了Parcelable接口的。

Android语言基础教程(239)Android创建Bound Service之使用Messenger类:[特殊字符] 用Messenger让跨进程通信so easy! 本文深度解析Android中如何使用Messenger创建Bound Service实现跨进程通信。从基本概念、工作原理到完整示例代码,详细讲解服务端和客户端的实现步骤,涵盖双向通信、死亡通知等进阶用法,并对比Messenger与AIDL的优劣,帮助开发者轻松掌握这一重要IPC机制。 阅读详情

相关推荐

安卓Messenger跨进程双向通信

要实现IPC(跨进程通信),可以使用官方给我们提供的Messenger机制和AIDL机制。 其中Messenger使用简单,适用于大部分多进程、单线程的应用, AIDL适用于较为复杂的多进程、多线程的应用。 这里我们介绍Messenger的用法,其底层也是使用AIDL实现的。 来看下Messenger用法 Reference to a Handler, which others can use ...

LuckyDucky的博客 1089

安卓Service中bindService和IBinder实现通信

2.新建一个继承自Service的类MyService,然后在AndroidManifest.xml里注册这个Service,在MyService里实例化一个MyBinder对象mBinder,并在onBind回调方法里面返回这个mBinder对象。5.当在点击事件发送一条消息后,mBinder会获取这条消息,并发送给MyService,在MyService 执行完成后,又会反馈给mBinder,并通过接口回调的方法,将成功信息反馈给Activity,打印日志如下。

weixin_41119184的博客 500

Android service(服务)中的绑定服务(binderService)详解与使用

前两篇文章中介绍了普通的后台服务及前台服务,这些服务有个共同的特点就是,启动服务的组件和服务之间没有任何关系。要想两者之间发生点关系,那就需要将两者之间绑定起来,这就用到了绑定服务。应用组件(客户端)可通过调用绑定到服务。然后,Android 系统会调用服务的onBind()方法,该方法会返回用于与服务交互的IBinder。绑定是异步操作,并且可立即返回,无需将IBinder返回给客户端。如要接收IBinder,客户端必须创建一个实例,并将其传递给。

superzhang6666的博客 1万+

Service基础(实现IBinder)(二)

实现IBinder,:在android中用于远程操作对象的一个基本接口,可以实现进度监控。

weixin_58308529的博客 3026

WPS中VBA支持库安装全攻略:从报错到一键解决

VBA作为Office生态中广泛使用的宏语言,是办公自动化的重要基础。WPS表格虽然兼容Excel文件格式,但出于技术路线与授权原因,默认并未集成完整的VBA引擎与开发环境,导致用户打开含宏文件时频繁遇到“找不到工程或库”“未找到VBA支持库”等报错。理解VBA支持库包含引擎与IDE两层结构,并掌握系统位数、版本匹配、安全软件拦截等前置条件,是成功部署的关键。通过可靠的安装源与规范流程完成配置后,即可实现在WPS中运行Excel宏、批量处理数据、自定义函数等自动化场景,显著提升报表处理效率。本文围绕WPS中

weixin_31102231的博客 306

icem二维非结构网格划分_ICEM CFD网格装配

正文共:718字7图 预计阅读时间:2分钟1 前言 对于一些大型的复杂的网格划分,可以将整个模型切分成多个子模型(二维几何用线切分,三维模型用面切分),然后对各个模型单独划分网格,最终装配在一起。这和机械设计的零件设计和装配设计有点相似,这个功...

weixin_39908758的博客 1625

Android Service回调和配置

Service 生命周期方法回调 创建服务,必须创建 Service 的子类(或使用它的一个现有子类)。可以重写一些回调方法,从而处理服务生命周期的某些关键方面,主要的回调方法有 onCreate()、onBind()、onRebind()、onStartCommand()、onStart()、onUnbind()、onDestroy()。 onCreate() 首次创建服务时,系统会(在调用 onStartCommand() 或 onBind() 之前)调用此方法来执行一次性设置程序。如果服务已在运行,则

ITRenj的博客 2031

手把手教你用DLP4500投影仪玩转结构光3D扫描(附固件烧录与序列设置避坑指南)

本文详细解析了如何使用DLP4500投影仪搭建结构光3D扫描系统,涵盖硬件组装、固件烧录、图案生成与优化等全流程。重点解决了固件烧录失败、图像格式错误等常见问题,并提供了实用的避坑指南和进阶技巧,帮助读者快速掌握DLP4500在3D扫描中的应用。

weixin_42662293的博客 301

Android Binder通信原理(三):service注册

上一文中详细分析了servicemanger 的启动流程,我们知道 servicemanager 作为 binder 机制中的一个特殊service,利用service map管理所有service,也是所有binder 通信的入口。本文着重分析 service 的注册流程,下一文着重分析service 的获取流程。

私房菜 2428

Prompt Airlines CTF通关实战:从提示词注入到多模态攻击的AI安全攻防演练

提示词注入(Prompt Injection)是当前大语言模型(LLM)应用面临的核心安全威胁之一,其原理在于攻击者通过精心构造的用户输入,覆盖或绕过系统预设的指令,从而操控模型行为。这种攻击手法的技术价值在于揭示了AI系统在理解与执行指令时存在的逻辑边界模糊性,可能导致数据泄露、越权访问等严重风险。在应用场景上,从基础的客服对话到结合视觉识别的多模态系统,都可能成为攻击面。本文以一场名为“Prompt Airlines CTF”的实战挑战为例,深入剖析了包括指令遗忘、上下文注入、工具调用滥用及多模态提示注

aodan5477的博客 515

MAPPO实战:从理论到代码的协作智能体训练指南

本文详细介绍了MAPPO算法在多智能体协作训练中的实战应用,从理论基础到代码实现全面解析。通过对比PPO与MAPPO的差异,深入讲解CTDE框架、网络架构设计、参数调优等关键环节,并提供实际项目中的调参经验和常见问题解决方案,帮助开发者快速掌握这一强化学习前沿技术。

weixin_42561040的博客 265

Android中通过Messenger与Service实现进程间双向通信

Android中的Service和其调用者既可以在同一个App中,也可以在不同的App。如果Service在App1中,而调用Service的客户端在App2中,那么我们就可以用Service实现进程间的相互通信。本文将介绍如何通过bindService和Messenger实现进程间通信(IPC),如果对bindService绑定服务和Binder不熟悉,可参见《Android中bindServic

孙群 1万+

【Dify精讲】第2章:后端服务架构深度剖析

Dify后端采用Flask应用工厂模式实现模块化开发,通过蓝图架构将API分为控制台、Web应用和服务接口三大模块。其设计亮点包括:1) 应用工厂模式支持多环境配置和独立测试;2) 蓝图分层管理实现API模块化,各模块职责清晰;3) 严格遵循RESTful原则设计API接口;4) 使用Flask-RESTful扩展简化API开发。这种架构既保持了Flask的灵活性,又实现了企业级应用的可维护性,是Flask项目架构的优秀实践案例。

wiyi9891的专栏 2126

利用Messenger跨进程通信

在进行跨进程通信的时候,可能很多开发者一开始想到的就是AIDL。AIDL,中文名称是android接口描述语言,是android系统中用于进行跨进程通信必须了解的。至于如何生成远程对象进行AIDL通信,大家可以看我之前写的一篇文章------对Binder的浅显分析及AIDL的使用。但其实,如果我们进行的跨进程通信逻辑比较简单,我们完全没必要自己生成AIDL,因为android已经为开发者封装了一

HyHarden的博客 3965

QGis二次开发 —— 1、win10/win11搭建Vs2017-QGis3.40.12环境(附Vs2017环境效果,附全部问题解决方法)(附:Qt助手加入QGis接口说明文档)

QGis二次开发 —— 1、Windows10搭建Vs2017-QGis环境(附Vs2017环境效果)(附:Qt助手加入QGisA接口说明文档)

1362

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Android IPC通信机制详解:Binder、AIDL、Messenger实战应用指南 [特殊字符]

Android进程间通信(IPC)是Android开发中的核心技术之一,它允许多个应用进程之间高效、安全地交换数据。在Android系统中,Binder、AIDL和Messenger是三种最重要的IPC通信机制,掌握它们对于构建高性能、稳定的Android应用至关重要。本文将详细介绍这三种核心通信方式的原理、使用场景和实战应用,帮助你快速掌握Android IPC通信的精髓。 ## 📊 And

gitblog_01075的博客 980

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Android 使用Messenger实现跨进程之间通信

1. MessengerMessenger可以理解为信使,顾名思义我们可以利用信使来传递信息(Message),没错利用Messenger来实现跨进程之间的通信就是传递Message对象,我们只需要做的是把数据放进去Message,然后使用Messenger的send方法将数据发送出去,像发送邮件一样。2. 实现一个Messenger的主要步骤: 既然说到是跨进程之间的通信,那么

佳威威的专栏 3352

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android Service、Messenger进程间通信

        Android进程间通信有很多种,这里记录使用Service和Messenger来通信。在开始之前需要了解一下Android组件之Service。        Aandroid组件使用Service有两种方式,一种是启动方式,第二种是绑定方式。因为第一种启动方式,在启动Service之后,不会得到Service的任何返回,所以对Service的控制不是很好,没有更多的交互。而第...

林序的博客 540

Android Activity与Service 的通信

1.Activity与service 间的通信,与service 与Activity是否在同一进程有关,若service与activity 在同一进程,则使用binderService 启动服务后通过返回的IBinder 对象来进行通信,若service是远程服务即service 运行与独立进程中,则activity与之的通信要用到AIDL(支持多线程)进行进程间通信(IPC)或者Messenger(信使,消息队列的机制,不支持多线程)进行通信。

Mr_DV_BKHM的博客 1553

Android 通过Messager与Service实现进程间双向通信案例详解

android message services

manshq163com的专栏 1019

Android bind service讲解以及跨进程通信

Android bind service讲解以及Messenger跨进程通信

skateboard1的专栏 4482

Android Messenger(跨进程)

1.Messager 我们知道,Service通过IBinder可以实现同一应用内同一进程的通信,而不同进程间的通信,最简单的方式就是使用Messenger服务提供通信接口。利用Messager,我们无需使用AIDL便可执行进程间通信 (IPC)。 首先看一下Messager的定义:允许实现基于消息的进程间通信的方式。 以下是Messenger使用的主要步骤: ①服务Service实现一个Handler,由其接收来自客户端的每个调用的回调; ②Handler用于创建Messenger对象(对Handler的

zenmela2011的专栏 3572

Android Service进程间双向通信之Messenger(系列4)

Android Service进程间双向通信之Messenger(系列4) 附录文章2虽然利用Service的Binder、bindService这些机制实现了Android Service与其他组件的相互通信,但实现手段并不唯一,Android体系架构中还有一个解决方案:利用Android...

chuoshao2508的博客 124

Activity和Service的交互方式

在开发过程中,经常会遇到Activity和Service进行相互通信、交换数据的需要,最常见的比如音乐播放器,使用Service在后台进行音乐播放,前台使用Activity显示界面,点击前台控件后需要告知Service,控制音乐的播放、暂停、切换下一首等,后台Service再将数据传给Activity来改变界面显示Activity和Service的交互方式主要有以下几种 通过广播进行交互 通过共享文

zh175578809的博客 1万+

android 服务的绑定,android使用Messenger绑定Service的多种实现方法

如果你需要在不同进程间通信,你可以在Service中使用Messenger来实现进程中通信。如果使用这种方式,Service中需要定义一个Handler对象(负责对客户端发送过来的Message进行响应)。Messenger可以共享给client一个IBinder对象,client通过这个IBinder对象向Service发送Message,而前面提到的Handler对象是这一切的基础。注:使用这...

weixin_42146274的博客 341
上一篇: Android Service--启动方式
下一篇: Android Service--AIDL
彼天
博客等级 码龄11年 37粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值