Android Framework--谈谈bindService

对应用开发者而言,bindService调用肯定是耳熟能详,本文将介绍framework如何表示和组织绑定关系,通过背后原理的分析来加深对Service的理解,除此之外,大家也能领略到框架代码是如何设计并带来一些启发。本文旨在理清主要的设计思路,并不会对所有细节展开描述,代码来自Android N。


bindService基本点

让我们回顾下bindService相关的知识点,这里以在Activity中调用bindService函数为例,函数原型如下:

public boolean bindService(Intent service, ServiceConnection conn,
        int flags)

指定目标Service的Intent,当目标Service的onBind()方法执行后,传进来的ServiceConnection接口就会得到回调,之前Service.onBind()返回的IBinder对象会作为参数传进来。从这个过程可以看到,系统要管理Service以及Service的使用方,维护它们之间的关系并在合适的时机执行某些回调。

bindService的最终实现在ContextImpl.java中,经过一系列处理调用到AMS.bindService方法,函数原型如下:

public int bindService(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, IServiceConnection connection, int flags, String callingPackage,
        int userId)

ContextImpl封装了很多信息,很容易就可以拿到诸如调用方进程的标识(IApplicationThread),以及调用方Activity的标识(token),这些信息是维护Service绑定关系的一部分材料,后面会再提到。

这里主要提下IServiceConnection参数,看命名好像跟ServiceConnection有关,但ServiceConnection是普通的接口,而IServiceConnection是Binder接口,应该有着某种映射关系,做为Service绑定的一个重要标识,有必要认清这个映射关系。

LoadedApk.java中的如下成员维护了该映射关系:

private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
    = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();

LoadedApk.ServiceDispatcher封装了ServiceConnection并包含一个IServiceConnection,可以认为LoadedApk.ServiceDispatcher和IServiceConnection是一对一的关系,Binder代理端通过调用IServiceConnection的接口,找到对应的ServiceConnection。

即:指定一个Context和ServiceConnection,有且只有一个IServiceConnection与之对应。
也就意味着,在不同的Activity中用同一个ServiceConnection调用bindService,最后传给AMS的是不同的IServiceConnection。其它推论可自行推导。


绑定关系的表示:ConnectionRecord

先了解下AMS中几个类的含义,这在后面的内容中要用到:

  • ServiceRecord:表示一个Service
  • ActivityRecord:表示一个Activity
  • ProcessRecord:表示一个应用进程

绑定关系至少包含如下信息:

  • 发起绑定的Intent
  • 绑定到哪个Service(ServiceRecord)
  • 哪个应用进程发起的绑定(ProcessRecord)
  • 哪个Activity发起的绑定(ActivityRecord)
  • 对应的IServiceConnection
  • flags或其它附加信息

ConnectionRecord用来表示绑定关系,即每次调用bindService都会生成该类对象,接下来讨论它是如何包含上述信息。

先看下它的成员变量:

/**
 * Description of a single binding to a service.
 */
final class ConnectionRecord {
    final AppBindRecord binding;    // The application/service binding.
    final ActivityRecord activity;  // If non-null, the owning activity.
    final IServiceConnection conn;  // The client connection.
    final int flags;                // Binding options.
    final int clientLabel;          
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值