Android Binder 框架层详解
Posted Jason_Wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder 框架层详解相关的知识,希望对你有一定的参考价值。
在了解完binder在native层以及驱动层的基本流程之后(参考Android如何注册服务到ServiceManager; Android 系统服务管家servicemanager启动过程详解 ),接下来这篇文章我们就来分析下binder在framework层(Java层)的具体原理与实现,重点围绕Java层如何添加服务到系统中这一主题展开。这里会谈到以下几个方面的问题:
- binder在Java层的具体架构与实现
- binder在Java层的ServiceManager又是如何实现
- android中如何加载注册binder相关的JNI方法
binder源码涉及面广,错误之处难以避免,欢迎各位批评指正
binder在Java层的具体实现
下图为Android框架层ServiceManager的结构简图。可以看到,框架层的ServiceManager
主要是为上层应用或服务提供一个统一的接口,用于向系统注册、查询或者获取服务,在另一端Binder
以及BinderProxy
则通过JNI方法调用native层的方法,以此来使用binder底层提供的接口。
ServiceManager
是一个不可初始化的类,其向外提供了addService
(添加服务)、getService
(获取服务)、checkService
(检查服务)、listService
列举所有系统服务等接口,并返回系统服务相关的IBinder
接口;IServiceManager
是一个接口,ServiceManager
正是通过该接口的实现ServiceManagerProxy
来调用native层的代码的;ServiceManagerProxy
代理对象有一个mRemote
变量,该变量实际是一个BinderProxy
实例,通过BinderProxy
就可以将Java层的RPC请求发送给native层,进而传递给binder驱动;IBinder
是RPC调用的一个抽象接口,代表了一个远程对象,通过该接口,我们可以向服务端发送RPC请求,该接口的核心函数是transact
:
public boolean transact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException;
这是一个同步调用,只有当服务端返回时,该函数才会返回结果。
源码(以下分析均基于Android N7.0): /android/frameworks/base/core/java/android/os/ServiceManager.java
接下来,就来看看上层如何调用ServiceManager
接口将系统服务注册到系统中的?
注册服务到servicemanager
在系统服务进程SystemServer
启动后,会注册很多服务,包括系统核心服务以及其他非系统服务:
private void run()
....
// 启动服务
try
//启动自举服务:PowerManager,DisplayManger 等等
startBootstrapServices();
//启动系统核心服务
startCoreServices();
//启动其他服务:Vibrator,TelecomRegistry,NetworkConnectivity...
startOtherServices();
catch (Throwable ex)
throw ex;
finally
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
....
private void startOtherServices()
....
telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
....
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
....
代码路径:/android/frameworks/base/services/java/com/android/server/SystemServer.java
调用ServiceManager
方法addService
:
public static void addService(String name, IBinder service)
try
getIServiceManager().addService(name, service, false);
catch (RemoteException e)
Log.e(TAG, "error in addService", e);
private static IServiceManager sServiceManager;
// 获取IServiceManager接口
private static IServiceManager getIServiceManager()
if (sServiceManager != null)
return sServiceManager;
// 获取servicemanager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
这里,BinderInternal.getContextObject()
究竟返回的是什么了?进去一看,发现getContextObject()
是一个本地化方法,需要通过JNI来调用native的代码:
// 一个本地化方法
public static final native IBinder getContextObject();
直接搜索 getContextObject
,发现在android_util_Binder.cpp
这个JNI文件中,定义了相应的JNI函数:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
// 获取serviemanager对应的binder对象: BpBinder(0)
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
// 这里返回的是什么了?
return javaObjectForIBinder(env, b);
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
....
// 新建一个BinderProxy对象?
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL)
// The proxy holds a reference to the native object.
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
val->incStrong((void*)javaObjectForIBinder);
// The native object needs to hold a weak reference back to the
// proxy, so we can retrieve the same proxy if it is still active.
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
// Also remember the death recipients registered on this proxy
sp<DeathRecipientList> drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
return object;
// 保存了BinderProxy类的信息
static struct binderproxy_offsets_t
// Class state.
jclass mClass;
jmethodID mConstructor;
jmethodID mSendDeathNotice;
// Object state.
jfieldID mObject;
jfieldID mSelf;
jfieldID mOrgue;
gBinderProxyOffsets;
从这里,我们大概可以判断出,javaObjectForIBinder
实际返回的是一个Java对象BinderProxy
,该对象有一个成员变量mObject
保存了一个本地的BpBinder
引用(参考Android如何注册服务到ServiceManager)。那么,与BinderProxy
紧密相关的结构体变量gBinderProxyOffsets
又是在何时被初始化的,这个疑问留到下一节“binder JNI方法的初始化”再来分析。暂时,我们知道BinderInternal.getContextObject()
返回的是一个servicemanager
对应的BinderProxy
。这样
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
就等价于: sServiceManager = ServiceManagerNative.asInterface(new BinderProxy());
,接着看一看asInterface
这个方法:
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
*/
static public IServiceManager asInterface(IBinder obj)
if (obj == null)
return null;
// BinderProxy直接返回null
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null)
return in;
// 新建一个ServiceManagerProxy(BindProxy)对象
return new ServiceManagerProxy(obj);
// ServiceManagerProxy构造函数,将BinderProxy实例保存到mRemote中
public ServiceManagerProxy(IBinder remote)
mRemote = remote;
源码: /android/frameworks/base/core/java/android/os/ServiceManagerNative.java
到这里,不难看出,调用ServiceManager.addService()
实际调用的就是ServiceManagerProxy
中的addService
方法:
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
// 调用BinderProxy的transact,发送RPC请求到servicemanager
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
// BinderProxy
final class BinderProxy implements IBinder
public IInterface queryLocalInterface(String descriptor)
return null;
....
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
....
return transactNative(code, data, reply, flags);
//调用JNI方法发送RPC请求
public native boolean transactNative(int code, Parcel data, Parcel reply,int flags) throws RemoteException;
那么,transactNative
又是如何调用到native层的方法的了?同样在android_util_Binder.cpp
中定义了BinderProxy
相关的JNI方法,其中transactNative
对应的JNI方法是android_os_BinderProxy_transact
,
static const JNINativeMethod gBinderProxyMethods[] =
/* name, signature, funcPtr */
"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder,
"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive,
"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor,
"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact,
"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath,
"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath,
"destroy", "()V", (void*)android_os_BinderProxy_destroy,
;
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
if (dataObj == NULL)
jniThrowNullPointerException(env, NULL);
return JNI_FALSE;
// gBinderProxyOffsets.mObject 就是指向servicemanger的远程对BpBinder(0)
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
if (target == NULL)
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
....
// BpBinder->transact(...)
status_t err = target->transact(code, *data, reply, flags);
....
到这了BpBinder
以后,就与之前的一篇文章Android如何注册服务到ServiceManager所讲的流程完全一样了。
binder JNI方法的初始化
在上文中提到,BinderInternal.getContextObject()
返回的是一个BinderProxy对象,同时该对象会引用一个native层的BpBinder
实例。那么,Android究竟是如何初始化JNI?又是如何根据gBinderProxyOffsets
这个结构体变量来构造一个Java对象BinderProxy
的了?
在Android启动过程中(参考Android开机流程,init进程通过init.zygotexxx.rc
来启动zygote
系统服务用于加载虚拟机实例(系统只有一个zygote进程,但是不同进程会有不同的VM实例,不同的VM实例会通过zygote
来共享一些共有的数据):
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
找到app_process
进程的代码入口:
int main(int argc, char* const argv[])
//获取runtime实例
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// ignore argv[0]
argc--;
argv++;
bool zygote = false;
bool startSystemServer = false;
++i; // Skip unused "parent dir" argument.
while (i < argc)
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0)
zygote = true;
niceName = ZYGOTE_NICE_NAME;
else if (strcmp(arg, "--start-system-server") == 0)
startSystemServer = true;
if (startSystemServer)
args.add(String8("start-system-server"));
....
....
// 创建第一个Dalvik VM实例,启动ZygoteInit进程
if (zygote)
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
else if (className)
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
....
源码: /android/frameworks/base/cmds/app_process/app_main.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
....
//初始化VM参数,创建VM实例
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0)
return;
onVmCreated(env);
// 注册JNI函数
if (startReg(env) < 0)
ALOGE("Unable to register all android natives\\n");
return;
....
//启动zygote进程:新建一个SystemServer进程,加载系统基础类与库
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL)
ALOGE("JavaVM unable to locate class '%s'\\n", slashClassName);
/* keep going */
else
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL)
ALOGE("JavaVM unable to find main() in '%s'\\n", className);
else
//调用ZygoteInit的main函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);
....
....
系统JNI方法都是在函数startReg(env)
中注册上的:
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
....
env->PushLocalFrame(200);
//注册所有的JNI函数到系统中
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0)
env->PopLocalFrame(NULL);
return -1;
env->PopLocalFrame(NULL);
return 0;
//gRegJni是系统JNI函数指针结构体数组
#define REG_JNI(name) name
struct RegJNIRec
int (*mProc)(JNIEnv*);
;
static const RegJNIRec gRegJNI[] =
....
REG_JNI(register_android_os_Process),
REG_JNI(register_android_os_SystemProperties),
//注册binder相关的JNI函数
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
REG_JNI(register_android_nio_utils),
....
;
找到register_android_os_Binder
函数所在源码:android_util_Binder.cpp
,在这个函数里,会注册所有和Binder框架层相关的JNI函数:
int register_android_os_Binder(JNIEnv* env)
//注册Binder.java对应的JNI
if (int_register_android_os_Binder(env) < 0)
return -1;
//注册BinderInternal.java对应的JNI
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
//注册BinderProxy.java对应的JNI
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
....
return 0;
正是在int_register_android_os_BinderProxy
这个函数里,初始化了结构体变量gBinderProxyOffsets
,其中mClass
指向一个全局的BinderProxy
引用,mConstructor
指向BinderProxy
的构造函数,而mObject
初始化为BinderProxy
的成员变量的ID值。这样初始化后,我们就可以使用gBinderProxyOffsets
直接返回一个BinderProxy
实例了。
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
//查找BinderProxy类
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
....
//注册BinderProxy相关的JNI
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
至此,我们对Binder框架层也有了一个比较深入的理解与认识。这里,对如何在框架层添加系统服务的流程做一个简单的总结:
- 调用
ServiceManager
的addService()
接口时,getIServiceManager
返回一个ServiceManagerProxy
对象; - 调用
ServiceManagerProxy
的addService()
接口; ServiceManagerProxy
中有一个mRomote
成员变量指向一个BinderProxy
对象,它是本地servicemanager的远程代理;- 通过JNI接口
transactNative()
发送数据到libbinder;
以上是关于Android Binder 框架层详解的主要内容,如果未能解决你的问题,请参考以下文章
[gitbook] Android框架分析系列之Android Binder详解