一、简介
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相比上面的有很多优点。
- 传输性能。socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。共享内存虽然无需拷贝,但控制复杂,难以使用。而Binder只有一次拷贝过程。
- 安全性考虑。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进程,我们都可以称之为系统服务!