Android Binder详解

本文详细介绍了Android中的Binder通信机制,包括为什么选择Binder而非其他IPC方式,Binder框架的构成,以及系统服务如何通过Binder实现。以Vibrator服务为例,展示了系统服务的注册、获取和服务调用流程,强调了Binder在系统服务中的关键作用。同时,讨论了系统服务与普通服务的区别,指出系统服务并不局限于特定的生命周期方法,而是提供特定功能并被ServiceManager管理的服务。

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

一、简介

Binder是Android中重要的进程间通信方式(IPC)。我们开发中使用的AIDL最终都是通过Binder实现。同时Android中提供很多系统服务(如AMS、PMS等),系统服务和我们的应用运行在不同的进程中,那么我们应用怎么使用系统提供的服务呢?其实简单点说这就是一个进程间通信,也是使用Binder实现。可见Binder在Android中是多么重要。

二、为什么使用Binder

Android的底层是Linux,Linux已经拥有管道,system V IPC,socket等IPC手段,Android可以直接使用Linux的进程间通信方式,但是为什么Android却重新开发Binder作为进程间通信方式呢?可想而知Binder相比上面的有很多优点。

  1. 传输性能。socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程共享内存虽然无需拷贝,但控制复杂,难以使用。而Binder只有一次拷贝过程
  2. 安全性考虑。Android作为一个开放式,拥有众多开发者的的平台,应用程序的来源广泛,确保智能终端的安全是非常重要的。终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期操作底层设备导致电池很快耗尽等等。传统IPC没有任何安全措施,完全依赖上层协议来确保。首先传统IPC的接收方无法获得对方进程可靠的UID/PID(用户ID/进程ID),从而无法鉴别对方身份。Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。使用传统IPC只能由用户在数据包里填入UID/PID,但这样不可靠,容易被恶意程序利用。可靠的身份标记只有由IPC机制本身在内核中添加。

基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder。

三、Binder框架

在Android系统中,运行在内核空间、负责各个用户进程通过Binder通信的内核模块叫做Binder驱动,Binder驱动虽然默默无闻,却是通信的核心。尽管名叫‘驱动’,实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是一样的。

Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。形形色色的Binder对象以及星罗棋布的引用仿佛粘接各个应用程序的胶水,这也是Binder在英文里的原意。

首先我们要理解我们说的 Binder 分为 Binder对象 和 Binder驱动,即 Binder驱动就是主要的内核模块,而这个 Binder对象是通讯的载体,可以自由的通过Binder驱动自由穿梭任意进程。所以客户端或者服务器就可以把数据放入Binder对象里,然后进行调用和通讯。Binder框架定义了四个角色:Server,Client,ServiceManager(以后简称SMgr)以及Binder驱动。其中 Server,Client,SMgr 运行于用户空间,驱动运行于内核空间这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,SMgr是域名服务器(DNS),驱动是路由器。

四、系统服务分析

下面以震动服务举例。

震动服务的使用

Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2000);

最终调用的是如下代码:

public Object getSystemService(String name) {
    return getBaseContext().getSystemService(name);
}

getBaseContext()获取的是ContextImpl的实例。我们看看ContextImpl中的getSystemService()方法。

public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}

SystemServiceRegistry负责管理系统服务(注册和获取),SystemServiceRegistry中getSystemService()的源码如下:

public static Object getSystemService(ContextImpl ctx, String name) {
    ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    return fetcher != null ? fetcher.getService(ctx) : null;
}

SYSTEM_SERVICE_FETCHERS是一个HashMap,通过我们服务的名字name,从这个HashMap里取出一个ServiceFetcher,再通过ServiceFetcher的getService()方法获取服务。ServiceFetcher是什么?它的getService()又是什么?既然他是从SYSTEM_SERVICE_FETCHERS这个HashMap里get出来的,那就找一找这个HashMap都put了什么。
SystemServiceRegistry的registerService()注册服务代码如下:

private static <T> void registerService(String serviceName, Class<T> serviceClass,
                                        ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}

这里往SYSTEM_SERVICE_FETCHERS里put了一对String与ServiceFetcher组成的key/value对,registerService()又是从哪里调用的呢?

在SystemServiceRegistry中有个静态代码块,这里面调用registerService()注册了很多服务。

static {
    registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
            new CachedServiceFetcher<ActivityManager>() {
                @Override
                public ActivityManager createService(ContextImpl ctx) {
                    return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
                }
            });

    registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
            new CachedServiceFetcher<Vibrator>() {
                @Override
                public Vibrator createService(ContextImpl ctx) {
                    return new SystemVibrator(ctx);
                }
            });
}

从注册的代码可知,注册的是SystemVibrator,所以上面getSystemService()获取的也是SystemVibrator。那我们看看SystemVibrator中vibrator方法是怎么实现的。

public void vibrate(int uid, String opPkg,
                    VibrationEffect effect, AudioAttributes attributes) {
    if (mService == null) {
        Log.w(TAG, "Failed to vibrate; no vibrator service.");
        return;
    }
    try {
        mService.vibrate(uid, opPkg, effect, usageForAttributes(attributes), mToken);
    } catch (RemoteException e) {
        Log.w(TAG, "Failed to vibrate.", e);
    }
}

虽然上面vibrator.vibrate(2000);只有一个参数,但是最终都会调用上面4个参数的方法。上面方法其实就是调用mService.vibrate(),那这个mService是什么呢?

public class SystemVibrator extends Vibrator {
    private static final String TAG = "Vibrator";

    private final IVibratorService mService;

    public SystemVibrator() {
        mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
    }
}

mService其实就是远程服务的本地代理对象,在构造函数中初始化。mService的类型是IVibratorService。IVibratorService是什么呢?IVibratorService是一个aidl文件,源码如下:

interface IVibratorService
{
    boolean hasVibrator();
    boolean hasAmplitudeControl();
    void vibrate(int uid, String opPkg, in VibrationEffect effect, int usageHint, IBinder token);
    void cancelVibrate(IBinder token);
}

上面的IVibratorService和IVibratorService.Stub是aidl文件生成的Java文件,具体在编译时生成,因为是系统内核代码,没有编译所以找不到Java文件的实现。那IVibratorService的具体实现在哪里呢?

具体由VibratorService实现,如下:

public class VibratorService extends IVibratorService.Stub

VibratorService实现了IVibratorService.aidl文件中定义的所有接口。

VibratorService是怎么注册ServiceManager的呢?在SystemServer里面startOtherServices()方法中注册的,代码如下:

private void startOtherServices() {
    traceBeginAndSlog("StartVibratorService");
    vibrator = new VibratorService(context);
    ServiceManager.addService("vibrator", vibrator);
    traceEnd();
}

大家有没有注意到一个问题。SystemVibrator构造函数中调用ServiceManager.getService("vibrator")和上面startOtherServices()不在一个进程中,那两个进程怎么都能访问ServiceManager呢?其实ServiceManager也是Binder实现的。

总结一下上面系统服务SystemVibrator的实现流程:

1、定义一个AIDL接口文件IVibratorService,定义系统服务接口

frameworks/base/core/java/android/os/IVibratorService.aidl

2、定义服务VibratorService,实现IVibratorService定义的接口

frameworks/base/services/java/com/android/server/VibratorService.java

public class VibratorService extends IVibratorService.Stub

3、将VibratorService添加到系统服务

frameworks/base/services/java/com/android/server/SystemServer.java

VibratorService vibrator = null;
...
//实例化VibratorService并添加到ServiceManager
Slog.i(TAG, "Vibrator Service");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
...

4、定义一个抽象类Vibrator,定义了应用中可以访问的一些抽象方法

frameworks/base/core/java/android/os/Vibrator.java

5、定义具体的类SystemVibrator继承Vibrator,实现抽象方法

frameworks/base/core/java/android/os/SystemVibrator.java

6、下面是使用SystemVibrator包装远程服务的调用。在SystemVibrator中通过IVibratorService的代理连接到VibratorService,这样SystemVibrator的接口实现里就可以调用IVibratorService的接口:

frameworks/base/core/java/android/os/SystemVibrator.java

这步会使用第3步添加到ServiceManager中的Service

public class SystemVibrator extends Vibrator {
    private static final String TAG = "Vibrator";

    private final IVibratorService mService;

    public SystemVibrator() {
        mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
    }

    public void vibrate(int uid, String opPkg,
                    VibrationEffect effect, AudioAttributes attributes) {
        if (mService == null) {
            Log.w(TAG, "Failed to vibrate; no vibrator service.");
            return;
        }
        try {
            mService.vibrate(uid, opPkg, effect, usageForAttributes(attributes), mToken);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to vibrate.", e);
        }
    }
}

7、在Context里定义一个代表Vibrator服务的字符串

frameworks/base/core/java/android/content/Context.java

public static final String VIBRATOR_SERVICE = "vibrator";

8、在SystemServiceRegistry里添加SystemVibrator的实例化过程,在静态代码块中注册

frameworks/base/core/java/android/app/SystemServiceRegistry.java

static {
    registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
        public Object createService(ContextImpl ctx) {
            return new SystemVibrator(ctx);
    }});
}

9、在应用中使用Vibrator的接口

Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2000);

10、为保证编译正常,还需要将AIDL文件添加到编译配置里

frameworks/base/Android.mk

LOCAL_SRC_FILES += \
...
core/java/android/os/IVibratorService.aidl \

五、系统服务和普通服务的区别

这里要注意,一说系统服务,有些朋友可能就想到onCreate()、onStartCommand()、onBind(),onStart()等等生命周期方法,其实我们这里说的系统服务跟我们做app开发时候的Service是不一样的。我们平时开发使用使用的服务必须是Service的子类,而系统服务并没有明确的定义,只要能向上层提供具体的功能(api),并且被纳入到ServiceManager中管理,运行在SystemServer进程,我们都可以称之为系统服务!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值