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 b = ProcessState::self()->getContextObject(NULL); // 这里返回的是什么了? return javaObjectForIBinder(env, b); } jobject javaObjectForIBinder(JNIEnv* env, const sp& 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 drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(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, "" , "()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与JS之间的互相调用交互(一)
- 硬件访问服务4之Android硬件访问服务框架及系统函数全详细实现
- android的binder机制研究(C++部分)
- 如何调用Android隐藏API
- 实现自己的Camera
- Android应用程序注冊广播接收器(registerReceiver)的过程分析
- android JNI层线程回调Java函数
- Android(安卓)Activity类应用技巧分享
- 箭头函数的基础使用