BindService 流程分析

本文详细分析了Android中BindService的流程,包括三个Binder对象:ActivityManagerProxy、IApplicationThread和IServiceConnection。讲解了从应用C通过Service连接到应用S的Binder对象传递过程,涉及四个进程间的调用,解释了AMS如何协调这些进程并传递Binder。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 问题介绍

  在应用S中实现一个非常基础的功能(XXInterface)。如果应用C需要用到S实现的功能。通常的做法是:在应用S中定义一个Binder对象b,b同时实现了功能接口(XXInterface)。然后将b传递给应用C,这样C就可以远程调用S中的函数。
  如何将S应用的Binder传递给应用C,主要有两种方法:一种是通过ServiceManager,S将Binder对象注册到ServiceManager中,然后C通过ServiceManager获取;一种是在S中定义一个Service,在Service的onbind函数中提供Binder对象,C应用调用BindService获取Binder对象。本文主要分析BindService获取Binder的流程。

2三个Binder对象

  应用S和应用C无法直接相互通信,他们的联系要通过AMS。所以BindService的过程涉及到应用(进程)S和AMS,以及应用(进程)C和AMS直接的交互。它们的通信过程涉及到了3个不同的Binder对象。
先简单介绍一下Binder的特点和这3个Binder对象。
  Binder 分为proxy(Client)和stub(Service)两种,一般proxy和stub位于不同的进程,通过proxy可以调用stub实现的方法。Binder远程调用的过程其实是将参数从进程C通过Binder驱动传到S,然后执行stub中对应的方法,然后将执行结果由S传到C的过程。
  Binder可以在进程之间相互传递,比如在proxy(进程C)调用stub(进程S)中的方法时,可以传入Binder类型的参数,这样Binder对象就由C传递到S。stub类型的Binder在传递到其他进程之后变为proxy类型,proxy类型传递之后仍然为proxy类型。在跨进程调用时把Binder对象作为参数,在Android中非常常见。

  1. 首先AMS(ActivityManagerService)本身就是一个Binder对象,他的代理对象是ActivityManagerProxy。客户端应用通过ActivityManagerProxy调用AMS的方法。比如应用C在执行BindService时,会通过ActivityManagerProxy调用AMS中的BindService方法。
  2. 实现了IApplicationThread接口的Binder。AMS主要通过该Binder调用客户端进程的函数。比如启动Activity时,AMS通过该Binder通知ActivityThread 创建Activity。这时 AMS是Client,ActivityThread 是Service。应用在通过ActivityManagerProxy 调用AMS的函数时,会把该Binder传递给AMS。
  3. 实现了IServiceConnection接口的Binder。AMS通过该Binder传递最终的Binder对象给 调用进程。该Binder也是客户进程传递给AMS的。

除了ActivityManagerProxy是从ServiceManager获取的,其他的Binder proxy 对象都是在进程间传递得到的。

Created with Raphaël 2.1.0 ServiceConnection ServiceConnection IServiceConnection IServiceConnection ContextImpl ContextImpl ActivityManagerService ActivityManagerService IApplicationThread IApplicationThread ActivityThread ActivityThread Service Service binderServiceCommon binderService 进程A跨进程调用AMS中的方法。 scheduleBindService AMS跨进程调用进程B中的方法。 handleBindService onBind publishService 进程B跨进程调用AMS中的方法。 connected AMS跨进程调用进程A中的方法。 onServiceConnected

进程间交互过程

3四个进程间调用

在上面的图中已经标明了这四个进程间调用。下面主要分析这四个调用传递的参数,返回的结果,涉及到的进程。

  1. A进程调用AMS 的BindService方法,传递的参数主要有两个 一个是Intent,包含绑定的Service信息。一个是IServiceConnection Binder对象,在AMS获得要A要的Binder(A调用BinderService要获取的Binder这里称为 Target Binder)对象之后,通过IServiceConnection Binder 将 Target Binder传递给进程A。这里还隐藏了一些细节,我们在调用Context 的BindService是,传递的是一个普通的ServiceConnection对象,并不是Binder 对象。其实是在调用AMS的BindService方法前将ServiceConnection包装为一个Binder对象IServiceConnection Binder。IServiceConnection Binder会调用ServiceConnection的onServiceConnected方法将Target Binder作为参数传递给进程A。
  2. AMS通过IApplicationThread Binder调用进程B的scheduleBindService方法,在scheduleBindService中会调用目标Service的onBind获取Target Binder。这里有一个问题,AMS是如何获得进程B的IApplicationThread Binder?分两种情况,1 如果进程B已经启动,会在AMS中有记录,通过A进程传给的Intent可以知道目标Service的进程,然后通过ProcessRecord可以得到IApplicationThread Binder。2 如果进程B没有启动,这时就比较复杂。通过Intent获得目标进程之后,AMS会先启动目标进程B,当B启动之后,会主动联系AMS,提供IApplicationThread Binder。详见代码。
  3. 进程B通过ActivityManagerProxy 调用AMS的publishService方法,将Target Binder传递给AMS。
  4. AMS 通过IServiceConnection 将Target Binder 传递给进程A。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值