在前面的博客中Android Binder框架实现之Native层服务注册过程源码分析我们重点分析讲解了Android Native层的服务怎么注册的,但是我们知道Android中绝大部分的服务都是通过Java来实现的,那么Java层的服务是怎么注册到ServiceManager服务大管家中的呢,这个就是我们今天这个篇章要重点分析的了。通过前面Natvie层服务的注册过程中我们知道其大致可以分为三大步骤,而我们的Java层的服务注册过程也是如此,其三大步骤如下:
而我们今天的篇章也将会围绕上述三个点来进行开展分析讲解,并且由于本篇章牵涉的知识点比较多,各位小伙伴们可要打起十分精神了!好了不多说了,直接开干!
framework/base/core/java/android/os/
---IInterface.java
---IServiceManager.java
---ServiceManager.java
---ServiceManagerNative.java(内含ServiceManagerProxy类)
framework/base/core/java/android/os/
---IBinder.java
---Binder.java(内含BinderProxy类)
---Parcel.java
framework/base/core/java/com/android/internal/os/
---BinderInternal.java
framework/base/core/jni/
---AndroidRuntime.cpp
---android_os_Parcel.cpp
---android_util_Binder.cpp
frameworks/native/libs/binder/BpBinder.cpp
frameworks/native/include/binder/IBinder.h
frameworks/native/libs/binder/Binder.cpp
frameworks/native/include/binder/Parcel.h
frameworks/native/libs/binder/Parcel.cpp
frameworks/base/core/jni/core_jni_helpers.h
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
在正式开始Android Framework层服务注册过程的源码分析前,还是老规矩磨刀不误砍柴工,先让我们来点前期知识储备再上马,更加事倍功倍!老子不打没有准备的仗!
通过前面的博客Android Binder框架实现之Native层服务注册过程源码分析我们知道了Android Binder的核心框架层实现是在C++层实现的,但是我们也知道Android的绝大部分开发者和从业人员都是以Java语言为主的,所以Android的妈咪谷歌也充分考虑到了这种情况在Android Framework层也实现了一套Binder机制。看到这里你是不是有点蒙蔽了,难不成Android还搞了两种Binder机制!当然不是,这里Android Framework层的Binder和Native层的Binder是相辅相成,协同合作从而完成Android Binder的千秋大业的。
前面遗留了一个小的知识点即Android Framework层和Native 层的Binder是怎么协同关联起来的呢?那就是Java和C++连接的万能膏药JNI技术了,Framework层的Binder通过JNI来调用(C/C++)层的Binder框架,从而为上层应用程序提供服务。 通过前面的博客我们知道在Native Binder层中,Binder采用的是C/S架构,分为Bn端(Server)和Bp端(Client)。而Java层在命名与架构上和Native也非常相近,基本上是无缝衔接,同样也实现了一套类似的IPC通信架构供应用开发使用(当然最后都是通过Native层的Binder框架实现的)。这里Framework层的Binder从另外一个层面来说,就是怼底层Native BInder的二次封装。Android BInder的整体框架图如下所示:
在前面的博客Android Binder框架实现之Native层服务注册过程源码分析中我们知道了Android Native Binder的涉及的类图关系如下(前方高能,请做好心理准备,要理清楚这其中的关系得花费一费时间的):
虽然我们在前面的博客对Android Native层的Binder类图关系有了详细的介绍,这里我们还是简单简单的归纳下:
BpBinder和BBinder共同继承与IBinder类,BpBinder是客户端进程中的Binder代理对象,BBinder是服务进程中用于IPC通信的工具对象,BpBinder类通过IPCThreadState类来与Binder驱动交互,访问服务进程中的BBinder,BpBinder代表了客户进程,BBinder代表了服务进程,数据从BpBinder发送到BBinder的整个过程就是Android系统的整个Binder通信过程,BpBinder与BBinder负责IPC通信,和上层业务并无关系。
Android系统的Binder通信实现了RPC远程调用,BpXXX和BnXXX则负责RPC远程调用的业务,XXX就代表不同的服务业务。BpXXX和BnXXX都实现了IXXX接口,IXXX定义了业务接口函数,BpXXX则是客户进程对服务进程中的BnXXX的影子对象,客户进程在调用服务进程中的某个接口函数时,只需调用BpXXX中的对应函数即可,BpXXX屏蔽了进程间通信的整个过程,让远程函数调用看起来和本地调用一样,这就是Android系统的Binder设计思想。
进程要与Binder驱动交互,必须通过ProcessState对象来实现,ProcessState在每个使用了Binder通信的进程中唯一存在,其成员变量mDriverFD保存来/dev/binder设备文件句柄。对于某个服务来说,可能同时接受多个客户端的RPC访问,因此Android系统就设计了一个Binder线程池,每个Binder线程负责处理一个客户端的请求,对于每个Binder线程都存在一个属于自己的唯一IPCThreadState对象,IPCThreadState对象封装来Binder线程访问Binder驱动的接口,同一个进程中的所有Binder线程所持有的IPCThreadState对象使用线程本地存储来保存。
那么Android Framework层的Binder类图关系是啥样的呢!怎么说呢和Android Native层Binder类图关系基本上是一一对应的,但是又有所差别,其基本类图关系如下:
是不是看到这个有点茫然无助的感觉,这里我们先简单介绍下(等在后续分析代码的时候可以将涉及到的相关类按图索翼,就理解起来容易了):
XXXManager:通过ServiceManager.getService方法可以获取到IXXXManagerService.Stub.Proxy对象,譬如我们通过该方法能获取到Android提供的的PMS,AMS,PKMS等相关服务的代理端。,然后我们可以通过该代理对象调用相关服务端完成指定的操作
IXXXManagerService.Stub.Proxy:其成员变量mRemote指向BinderProxy对象,IXXXManagerService.Stub.Proxy调用的相关方法最终是交由mRemote来完成相关操作的(注意这里的mRemote也是一个一个代理,真正完成相关的是在服务端)
IXXXManagerService.Stub:其方法asInterface()返回的是IXXXManagerService.Stub.Proxy对象,XXXManager便是借助IXXXManagerService.Stub类来找到IXXXManagerService.Stub.Proxy
Binder:其成员变量mObject和方法execTransact()用于native方法,和Native层Binder的BBinder对应
BinderInternal:内部有一个GcWatcher类,用于处理和调试与Binder相关的垃圾回收。
IBinder:接口中常量FLAG_ONEWAY:客户端利用binder跟服务端通信是阻塞式的,但如果设置了FLAG_ONEWAY,这成为非阻塞的调用方式,客户端能立即返回,服务端采用回调方式来通知客户端完成情况。另外IBinder接口有一个内部接口DeathDecipient(死亡通告)。
BinderProxy: 该类实现了IBinder接口,和Android Native Binder层的BpBinder是对应关系,最后借助BpBinder完成Binder间的数据传输
是不是上面的描述的描述还是有点抽象,那么以我们Framework层的ServiceManager(Java层的服务大管家)为例,将相关的实现带入类图(通常涉及到具体的实现会对Proxy和Stub类进行一下封装)。
通过前面1.1章节我们知道Android Framework层和Native 层Binder之间是通过JNI串联起来的,那么这两者之间的层级关系如何呢?我这边小小的归纳总结了一下,可以用如下的两个图来表示:
如果对Android Binder涉及的类图关系也进行一次分层划分,那么整个Binder从kernel至,Native,JNI,Framework层所涉及的全部类可以使用如下gityuan大神的图归纳总结一下:
通过前面博客Android之init进程启动源码分析我们可知Android Native Binder的大管家servicemanager进程及其相关的Native Binder Service进程是在init进程解析相关的init.xx.rc文件中的service块时启动的。那么我们的Android Framework Binder框架又是何时启动的呢?也许对Android启动过程有一定了解的小伙伴们会说是在system_server进程启动过程中,此时会启动相关核心服务并将其加入ServiceManager中。其实不然在Android Zygote进程启动源码分析指南中,我们知道Zygote进程会调用AndroidRuntime::startReg函数注册一系列的JNI函数,而这其中就包括我们的Android Framework层的Binder框架层相关的JNI,此时就标志着Framework层BInder框架的启动,而不是到了system_server进程才开始启动的。至于为什么要在此处注册,这个就留个小伙伴们自行思考了?
//AndroidRuntime.cpp
static const RegJNIRec gRegJNI[] = {
...
REG_JNI(register_android_os_Binder),//详见章节2.2
...
}
int AndroidRuntime::startReg(JNIEnv* env)
{
...
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
...
return 0;
}
这个流程没有过多好讲的,就是注册一系列的JNI方法,其中gRegJNI是一个数组保存了一系列的待注册的JNI方法列表,而这其中就包括我们今天的主人公Framework Binder相关的JNI方法register_android_os_Binder。
这里顺带说一句,如果对JNI有不熟悉的小伙伴,强烈建议先阅读一下JNI/NDK入门指南,带你开启JNI世界的大门!
//android_util_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
//注册Binder类的JNI方法
if (int_register_android_os_Binder(env) < 0)//详见章节2.3
return -1;
//注册BinderInteral类的JNI方法
if (int_register_android_os_BinderInternal(env) < 0)//详见章节2.4
return -1;
//注册BinderProxy类的JNI方法
if (int_register_android_os_BinderProxy(env) < 0)//详见章节2.5
return -1;
...
return 0;
}
register_android_os_Binder函数比较简单,就是调用另外的函数继续进行相关的Binder的JNI方法的注册。
在继续分析相关的函数前,我们来先看一下frameworks/base/core/jni/core_jni_helpers.h中对JNI环境提供的基本函数进行二次封装的相关工具函数集合(为啥要先介绍,因为后续会用到这些工具函数),如下:
//frameworks/base/core/jni/core_jni_helpers.h
/*
*查找对应Java类
*/
static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
jclass clazz = env->FindClass(class_name);
LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
return clazz;
}
/*
*返回类的实例(非静态)域的属性ID
*/
static inline jfieldID GetFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
const char* field_signature) {
jfieldID res = env->GetFieldID(clazz, field_name, field_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
return res;
}
/*
*返回Java类或者接口实例非静态方法的方法ID
*/
static inline jmethodID GetMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
const char* method_signature) {
jmethodID res = env->GetMethodID(clazz, method_name, method_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s", method_name);
return res;
}
/*
*返回类的静态域的属性ID
*/
static inline jfieldID GetStaticFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
const char* field_signature) {
jfieldID res = env->GetStaticFieldID(clazz, field_name, field_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
return res;
}
/*
*返回类的静态方法ID
*/
static inline jmethodID GetStaticMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
const char* method_signature) {
jmethodID res = env->GetStaticMethodID(clazz, method_name, method_signature);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static method %s", method_name);
return res;
}
/*
*基于局部引用创建一个全局引用
*/
template <typename T>
static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
jobject res = env->NewGlobalRef(in);
LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference.");
return static_cast<T>(res);
}
/*
*注册Java类对应的JNI方法
*/
static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
const JNINativeMethod* gMethods, int numMethods) {
int res = AndroidRuntime::registerNativeMethods(env, className, gMethods, numMethods);
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
return res;
}
小伙伴们,这个标题没有错,不要怀疑我是把2.2的标题给复制了一篇粘贴过来了。
//android_util_Binder.cpp
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
//kBinderPathName = "android/os/Binder",用来查找kBinderPathName路径所属的类,即我们的Binder.java
jclass clazz = FindClassOrDie(env, kBinderPathName);//关于该函数的功能参见2.2
//将Java层的Binder类保存到mClass中
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);//关于该函数的功能参见2.2
//将Java层execTransact()方法保存到mExecTransact变量
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");//关于该函数的功能参见2.2
//将Java层的mObject属性保存到mObject中
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");//关于该函数的功能参见2.2
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
有了前面章节2.2最后关于JNI工具函数的的知识铺垫int_register_android_os_Binder函数应该理解起来就很简单了,主要干了两件事情:
//android_util_Binder.cpp
static struct bindernative_offsets_t
{
jclass mClass;// 保存Java层Binder类信息
jmethodID mExecTransact;// 保存Java层Binder类execTransact()方法ID
jfieldID mObject;//保存Java层Binder类mObject属性域ID
} gBinderOffsets;
这里的gBinderOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层Binder类本身以及其成员方法execTransact()和成员属性mObject的,这为JNI层访问Java层提供通道。另外通过查询获取Java层Binder信息后保存到gBinderOffsets,而不是每次在需要使用Binder的时候再来进行相关的查找这样能大幅的提高效率,这是由于每次查询需要花费较多的CPU时间,尤其是频繁访问时,但是我们这里提前使用额外的结构体来保存这些信息,是以空间换时间的方法来达到提升效率(现在的Android设备存储空间都比较大,所以这些开销基本可以忽略不计)。
//jni.h
typedef struct {
const char* name;//Java本地方法名称
const char* signature;//Java本地方法签名
void* fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderMethods[] = {
/* name, signature, funcPtr */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
这里的gBinderMethods是一个全局的结构体数组,通过RegisterMethodsOrDie将该结构体数组中的本地方法和JNI函数建立一一对应的关系,通俗的来讲就是JNI的动态注册。
经过上面的操作以后建立了Java层到JNI层的访问通道,进而为打通Java层和Native层之间的通道做好了前期的准备,此时也标志着Framework层的Binder和Native 层Binder之间的连接桥梁已经开始进行施工了。
//android_util_Binder.cpp
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
return RegisterMethodsOrDie(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
有了前面的分析,这里的流程基本就是依葫芦画瓢了,int_register_android_os_BinderInternal函数主要干了如下两件事情:
//android_util_Binder.cpp
static struct binderinternal_offsets_t
{
jclass mClass;//保存Java层BinderInternal类信息
jmethodID mForceGc;//保存Java层BinderInternal类forceBinder()方法ID
} gBinderInternalOffsets;
这里的gBinderInternalOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层BinderInternal类本身以及其成员方法forceBinder()信息。
这里的gBinderInternalMethods也是一个全局的结构体数组,保存的是BinderInternal类本地方法以及对应的JNI方法对应关系表,如下所示:
//jni.h
typedef struct {
const char* name;//Java本地方法名称
const char* signature;//Java本地方法签名
void* fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = {
/* name, signature, funcPtr */
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
分析至此,Framework层的BinderInternal类和JNI之间的关系已经建立,进而为后续Android Framewrok层Binder和Native层Binder关系的建立夯实了坚定的基础。
//android_util_Binder.cpp
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
//gErrorOffsets保存了Error类信息
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//gBinderProxyOffsets保存了BinderProxy类的信息
//其中kBinderProxyPathName = "android/os/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");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
"Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
//gClassOffsets保存了Class.getName()方法
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
依然是老套路,还是来个依葫芦画瓢算了,int_register_android_os_BinderProxy函数主要干了如下两件事情:
//android_util_Binder.cpp
static struct binderproxy_offsets_t
{
jclass mClass;
jmethodID mConstructor;
jmethodID mSendDeathNotice;
jfieldID mObject;
jfieldID mSelf;
jfieldID mOrgue;
} gBinderProxyOffsets;
这里的gBinderProxyOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层BinderProxy类本身以及其成员方法ID和变量域ID等相关信息。
这里的gBinderProxyMethods也是一个全局的结构体数组,保存的是BinderProxy类本地方法以及对应的JNI方法对应关系表,如下所示:
//jni.h
typedef struct {
const char* name;//Java本地方法名称
const char* signature;//Java本地方法签名
void* fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
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},
};
分析至此,Framework层的BinderProxy类和JNI之间的关系已经建立,进而为后续Android Framewrok层Binder和Native层Binder关系的建立夯实了坚定的基础。
到这里Android Framework层Binder框架在Zygote进程中的初始化也告一段落了,通过这一些列的初始化工作Android Framework层的Binder和JNI建立起了相关的关联,进而为后续的和Native Binder关联建立起了通道。此时关于Android Framework层Binder相关类和JNI之间的联系,可以使用下述的图示来表示,如下:
在博客中Android system_server启动大揭秘我们讲述了在system_server启动的过程中会启动一系列的Android Framework层的BInder服务,这里我们以AMS(的注册为例来说明,Android Framework层的Binder服务是怎么注册到servicemanager中的(注意这里我们只重点关注AMS的注册,而对于AMS本身的功能不做过多分析和说明)。
在AMS服务启动的setSystemProcess阶段会将自己注册到servicemanager进程中,源码如下:
//ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
...
public void setSystemProcess() {
...
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);//详细分析过程见3.1
...
}
...
//ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
/**
*看着精简的两句代码,蕴含着无限的能力
*这里会分为两个步骤来分解:
*一:getIServiceManager()获取ServiceManagerProxy代理端,详见章节3.2
*二:调用ServiceManagerProxy代理端addService方法注册服务,详见章节3.5
*/
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
ServiceManager.addService会调用getIServiceManager()方法获取SMN的代理端SMP,并且调用其方法addService将AMS注册到servicemanager中。
//ServiceManager.java
private static IServiceManager sServiceManager;
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
//等价于new ServiceManagerProxy(new BinderProxy(0))
/**
*看着精简的两句代码,蕴含着无限的能力,其实我是想吐糟谷歌你为啥就不能好好的写代码呢
*这里会分为两个步骤来分解:
*一:BinderInternal.getContextObject(),创建new BinderProxy(0),详见章节3.2.1
*二:调用ServiceManagerNative.asInterface(),创建SMP服务代理端,详见章节3.3
*/
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
该段代码短小精悍,但是却孕育着无限的力量!getIServiceManager采用了单例模式最终获取的是new ServiceManagerProxy(new BinderProxy(0)),不要问我是怎么来的,我只能说路途艰辛且行且珍惜!
//BinderInternal.java
public class BinderInternal {
...
public static final native IBinder getContextObject();
...
}
一看就是一个本地方法,通过前面的章节我们知道在android_util_Binder.cpp中完成了对BinderInternal 本地方法的注册,其对应的JNI函数为android_os_BinderInternal_getContextObject,让我们前往一探究竟。
//android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
//此处返回的是new BpBinder(0)
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
//此处返回的是new BinderProxy(0)
return javaObjectForIBinder(env, b);//详见2.3.2
}
关于ProcessState::self()->getContextObject(NULL)这里就不展开进行具体相关的分析了,详见博客Android Binder框架实现之defaultServiceManager()的实现的2.3章节,总之最后如上代码会转换成new BpBinder(0)返回回来。
//Binder.cpp
bool IBinder::checkSubclass(const void* /*subclassID*/) const
{
return false;
}
//android_util_Binder.cpp
//此处的入参val是BpBinder
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {//返回false,这个得val是BpBinder其父类是IBinder并且没有重写checkSubclass,所以直接返回false不会走该分支
// One of our own!
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
// For the rest of the function we will hold this lock, to serialize
// looking/creation/destruction of Java proxies for native Binder proxies.
AutoMutex _l(mProxyLock);
// Someone else's... do we know about it?
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {//第一次object为null
jobject res = jniGetReferent(env, object);
if (res != NULL) {
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//创建BinderProxy对象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object.
//BinderProxy.mObject成员变量记录BpBinder对象
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));
//将BinderProxy对象信息附加到BpBinder的成员变量mObjects中
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);
//BinderProxy.mOrgue成员变量记录死亡通知对象
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;
}
还记得大明湖畔的夏雨荷吗,走错片场了!还记得章节2.5 int_register_android_os_BinderProxy吗,里面有将BinderProxy类的相关信息保存到了gBinderProxyOffsets结构体中,而在这里正是借助这个gBinderProxyOffsets结构体保存的信息,以BpBinder(0)为参数在C++层通过JNI操作创建Java层的BinderProxy实例对象,并把BpBinder对象地址保存到BinderProxy.mObject成员变量中。至此BinderInternal.getContextObject()就已经分析完成了,将其扩展开来可以得到如下代码:
BinderInternal.getContextObject() = new BinderProxy(0);
//ServiceManagerNative.java
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
...
//注意这里的入参是BinderProxy
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
//由于入参为BinderProxy,其方法queryLocalInterface返回为null
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);//详见3.3.1
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);//详见3.3.2
}
...
}
我们通过前面的分析可知ServiceManagerNative.asInterface的入参为BinderProxy,然后调用其方法queryLocalInterface返回为null,所以ServiceManagerNative.asInterface(new BinderProxy(0))最后等价为:
ServiceManagerNative.asInterface(new BinderProxy(0)) = ServiceManagerProxy(new BinderProxy(0))
//BinderProxy.java
final class BinderProxy implements IBinder {
...
public IInterface queryLocalInterface(String descriptor) {
return null;
}
...
}
无需多言,只是为了验证前面的结论!
//ServiceManagerNative.java
class ServiceManagerProxy implements IServiceManager {
//这里的入参为BinderProxy(0)
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}
ServiceManagerProxy的构造比较简单,就是将mRemote指向入参BinderProxy(0),该BinderProxy对象对应于BpBinder(0),其作为Binder代理端,指向Native层大管家service Manager。
//ServiceManager.java
private static IServiceManager sServiceManager;
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
//等价于new ServiceManagerProxy(new BinderProxy(0))
/**
*看着精简的两句代码,蕴含着无限的能力,其实我是想吐糟谷歌你为啥就不能好好的写代码呢
*这里会分为两个步骤来分解:
*一:BinderInternal.getContextObject(),创建new BinderProxy(0)
*二:调用ServiceManagerNative.asInterface(),创建SMP服务代理端
*/
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
至此getIServiceManager就分析完成了,其基本功能就是获取SMP服务端代理对象SMP,其获取流程可以分为如下两步:
BinderInternal.getContextObject() 创建一个Java层的BinderProxy(0)对象,该对象与C++层的BpBinder(0)一一对应;
ServiceManagerNative.asInterface(obj) 创建一个Java层面的ServiceManagerProxy代理对象,作用与C++层的BpServiceManager相同。
对于上述的流程归纳总结起来即先创建一个BpBinder(0)用于和Binder驱动交互,接着以BpBinder(0)为参数创建Java层的BinderProxy(0)用于数据的传输,接着最后以BinderProxy(0)为参数创建ServiceManagerProxy用于数据的打包。上述对应的关系可以详见下列示意图:
//ServiceManagerProxy.java
//这里的入参为三个分别是服务的名字(主要供第三方通过name想servicemanager大管家查询),服务的实体
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);
//最终等价于writeStrongBinder(new JavaBBinder(env, obj))
data.writeStrongBinder(service);//详见3.6
data.writeInt(allowIsolated ? 1 : 0);
//成员变量mRemote指向BinderProxy
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//详见3.8
reply.recycle();
data.recycle();
}
回到章节3.1,如果说前面的分析是开胃菜,那么到这里就要开始正餐了。我们调用getIServiceManager得到了SMP,接着继续调用其方法addService注册Framework层系统服务。其中主要涉及到了Parcel对数据的打包和传输,关于Parcel对基本数据的打包和写入可以详见博客Android Binder框架实现之Parcel详解一,这里我们会重点关注Binder类型对象的写入和Parcel类型数据的transact。
//Parcel.java
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}
依然是老套路,通过JNI调用C++层的Parcel实现Binder对象的写入。
//android_os_Parcel.cpp
//注意此处的入参object是Framework层Binder服务实体
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);//强制将nativePtr转换成Parcel对象,这个见怪不怪了
if (parcel != NULL) {
//等价于parcel->writeStrongBinder(new JavaBBinder(env, obj));
/**
*我只能说此处代码短小精悍,力量无穷啊,此处的代码逻辑分为两步
*第一:调用ibinderForJavaObject创建JavaBBinder,详见章节3.6.2
*第二:调用C++层的Parcel对象函数writeStrongBinder写入JavaBBinder,这个内容有点只能详见3.7了
*/
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
谷歌的Binder是设计思想是如此的巧妙,可是为什么代码逻辑排版就不能好好的整理一下呢!android_os_Parcel_writeStrongBinder函数逻辑看着比较简单,也就干了两件事情(但是分析起来你懂的):
在正式开始该函数分析前,让我们回过头捋一捋我们是要将什么Framework层Binder服务注册到servicemanager中的,对了是AMS,我们看看其继承和实现关系,如下:
//ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
...
}
//ActivityManagerNative.java
//这里的父类Binder是重点
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
...
}
平谈无奇,没有啥重点!那还能咋样呢,继续往下分析Binder.java的构造方法,逻辑如下:
//Binder.java
private native final void init();
public class Binder implements IBinder {
public Binder() {
init();
...
}
}
又是老套路,调用到了JNI层的函数,如下所示:
//android_util_Binder.cpp
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();//构建一个JavaBBinderHolder对象
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
//增加引用计数
jbh->incStrong((void*)android_os_Binder_init);
/*
*将JavaBBinderHolder对象保存在gBinderOffsets.mObject中,此时的gBinderOffsets.mObject已经在Zygote启动中和Binder.java中的mObject绑定了
*/
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
这个函数还干了一点事情,捯饬捯饬来说可以分为两步:
此时的你我想会有一个疑问就是gBinderOffsets这些的初始化不都是在Zygote进程中吗,我注册AMS服务是在system_server进程中进行的,这个gBinderOffsets能用不。我只能说孩子不要忘了你来自那里,当然不是天上了,那怕你贵为system_server进程你不也是Zygote进程孵化出来的,我们的Zygote进程也是无私的你继承了其所有也包括上面初数化的相关变量空间。
最后我要说一句,真的,我不是闲的蛋疼才加上上面的描述的,更加不是为了凑字数的,再说也没有稿费可骗啊!真的你们要相信我,接着继续分析ibinderForJavaObject。
//android_os_Parcel.cpp
//此时的入参obj为Binder.java实例对象
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
//这里的IsInstanceOf和Java中的instanceof方法有点类似
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//检测是否是Java层Binder类或者子类
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);//以Binder(Java层)为参数生成JavaBBinderHolder(C++层),详见3.6.5
return jbh != NULL ? jbh->get(env, obj) : NULL;//详见章节3.6.6
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {//检测是否是Java层BinderProxy类或者子类
return (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
是吗,真的没有骗你吗!通过前面我们知道AMS是Binder的子类,所以会走第一个分支即此时的入参obj和gBinderOffsets.mClass保存的Bindre信息是属于同一类型都是Binder类型,这里的JNI提供的函数IsInstanceOf和Java层的instanceof方法类似即判断两个对象是否属于同一个类或者及其子类。接着根据Binde(Java)生成JavaBBinderHolder(C++)对象,然后调用其get返回一个IBinder对象实例。
//android_util_Binder.cpp,又是在这个文件里面,你干的活还真多
class JavaBBinderHolder : public RefBase
{
public:
...
sp<JavaBBinder> getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp<JavaBBinder> mBinder;//注意这里的指针是wp类型的,即C++中的弱引用,可能会被回收
};
JavaBBinderHolder它是如此朴实无华,没有构造函数,既然你这么绝情也不要怪我无意,老子不分析你了。
//android_util_Binder.cpp
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();//判断是会被回收或者已经创建了
if (b == NULL) {
b = new JavaBBinder(env, obj);//创建JavaBBinder,注意参数obj为Binder.java实例对象,详见3.6.7
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
通过前面的章节我们知道JavaBBinderHolder有一个名为mBinder的JavaBBinder对象的弱指针(C++层),mBinder是否被重新赋值的关键有两点第一其是否是第一次进入,第二由于mBinder是一个wp类型弱引用所以可能被系统垃圾回收机制回收,所以每次使用它的时候必须先行判断一下。
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
}
这里注意JavaBBinder的父类为BBinder,并且以传递过来的参数object构建一个全局的mObject引用(object为Java层的Binder.java)。
分析至此,各位小伙们是不是对于JavaBBinder (C++),JavaBBinderHolder(C++),Binder(Java)三者之间的关系有理不断剪还乱的感觉!真的不要怪Android的妈咪谷歌,它这么做也是为了世界和平!这里我们可以使用下述的示意图来表述三者之间的关系:
上述三者是怎么关勾搭上的呢(不,关联上的),这要回到3.6.4 ibinderForJavaObject说起了:
是不是还是有点一脸蒙蔽,但是既然现在三者之间的关系已经创建既成事实了,那么就着这三者之间的关系再来捋一捋:
Android Framework层的Binder服务必须继承于Binder类,而我们的Binder对象在构造服务时,会首先在C++层构造一个JavaBBinderHolder对象,并将该对象的指针保存到Java层的服务的mObject变量中,即建立起了Binder(Java)到JavaBBinderHolder(C++)之间的关系了
而我们的C++层的JavaBBinderHolder对象通过成员变量mBinder指向一个C++层的JavaBBinder对象,JavaBBinder类继承于BBinder类,是服务在C++层的表现形式,此时建立起了JavaBBinderHolder(C++)和JavaBBinder(C++)之间的关系了
而我们的C++层的JavaBBinder对象又通过成员变量mObject指向Java层的Binder服务对象,即建立起了Binder(Java)和JavaBBinder(C++)之间的关联了
对于这三者之间的关系,我只想说一句话造孽啊!
在前面的博客Android Binder框架实现之Native层服务注册过程源码分析中此处的源码相关逻辑其实已经有分析了,但是为了整体框架的完整和从上到下的贯通我们还是简单过一下(其实我是舍不得各位小伙伴们)!
//Parcel.cpp
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)//注意这里的入参val为JavaBBinder
{
return flatten_binder(ProcessState::self(), val, this);//详见3.7.1
}
该函数没有多说的直接调用flatten_binder写将入参参数JavaBBinder写入C++层Parcel容器中。
//Parcel.cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == NULL) {
ALOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;//远程Binder
obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
obj.handle = handle;//记录Binder代理的句柄
obj.cookie = 0;
} else {
obj.type = BINDER_TYPE_BINDER;//本地Binder进入该分支
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);//记录Binder实体的指针
}
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = 0;
obj.cookie = 0;
}
return finish_flatten_binder(binder, obj, out);
}
我们这里的入参binder为JavaBBinder对象实例,我们回忆回忆其继承关系,其关系如下
IBinder(C++) ----> BBinder(C++) ---> JavaBBinder(C++)
而我们的BBinder的localBinder函数实现如下:
//Binder.cpp
BBinder* BBinder::localBinder()
{
return this;
}
所以精简过后的flatten_binder函数如下:
//Parcel.cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
...
} else {
obj.type = BINDER_TYPE_BINDER;//本地Binder进入该分支
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);//记录Binder实体的指针
}
} else {
...
}
return finish_flatten_binder(binder, obj, out);//详见章节3.7.2
}
此时重要大哥flat_binder_object 要上场了,我们可以将其理解为它是用来专门描述BBinder对象的,将其带入实际代码,会得到如下的逻辑:
此时此刻关于flatten_binder扁平化的分析已经分析完毕了,此时flat_binder_object结构体中数据的映射关系如下:
//Parcel.cpp
inline static status_t finish_flatten_binder(
const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
{
return out->writeObject(flat, false);
}
好了这里真的不能扩展了,我们只需要知道此时会将扁平化的Binder实体数据写入Parcel的存储结构中,具体的真的小伙伴们只能异步到Android Binder框架实现之Native层服务注册过程源码分析中了(因为有些小伙们,可能只是向了解Framewrok层的实现)。