源码基于:Android R

0. 前言

在阐述相关的知识点,先整理个框架图,后面带着框架图来分析过程:

Java 端对于binder 使用大致分为:

  • Java client Java service
  • Java client native service

Java 端service 的注册使用 ServiceManager.addService()

Java 端service 的获取使用 ServiceManager.getService()

入口都是通过 ServiceManager.java,文件位于frameworks/base/core/java/android/os/ServiceManager.java

在分析addService 和getService 之前,需要了解Binder 最终是会调用到native 端,那么,Java 中间就需要通过JNI,所以在此之前需要了解JNI 的注册过程。

1. Binder JNI 注册

了解zygote 启动过程的同学应该知道 zygote 在启动时首先会创建虚拟机,然后再通过 startReg() 注册系统所需要的JNI 接口。

frameworks/base/core/jni/AndroidRuntime.cpp/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{...if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {env->PopLocalFrame(NULL);return -1;}...
}

注册的接口定义在:

frameworks/base/core/jni/AndroidRuntime.cppstatic const RegJNIRec gRegJNI[] = {REG_JNI(register_com_android_internal_os_RuntimeInit),REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),REG_JNI(register_android_os_SystemClock),REG_JNI(register_android_util_EventLog),REG_JNI(register_android_util_Log),REG_JNI(register_android_util_MemoryIntArray),...REG_JNI(register_android_os_Binder),...

数组很长,这里不过多粘贴,binder 相关的注册函数有:

        REG_JNI(register_android_os_Binder),

最终会调用到函数register_android_os_Binder():

frameworks/base/core/jni/android_util_Binder.cppint register_android_os_Binder(JNIEnv* env)
{if (int_register_android_os_Binder(env) < 0)return -1;if (int_register_android_os_BinderInternal(env) < 0)return -1;if (int_register_android_os_BinderProxy(env) < 0)return -1;...

剩下来就不过多分析了,感兴趣的同学可以进入详细查看源码流程 (当然,下面遇到也会顺带分析下),这里只需要知道的是Java 端的Binder 需要native 操作的JNI 接口都是在zygote 启动时就注册好了。

2. ServiceManager 的代理

无论是ServiceManager.addService() 还是ServiceManager.getService() 最终都是需要与native 通信,那需要获取到 ServiceManager 的代理。即函数 getIServiceManager()

frameworks/base/core/java/android/os/ServiceManager.java private static IServiceManager getIServiceManager() {if (sServiceManager != null) {return sServiceManager;}// Find the service managersServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));return sServiceManager;}

这里主要关注两点:

  • BidnerInternal.getcontextObject()
  • ServiceManagerNative.asInterface()

2.1 BinderInternal.getContextObject()

frameworks/base/core/java/com/android/internal/os/BinderInternal.javapublic static final native IBinder getContextObject();

这个需要调用 JNI 接口,而这个接口注册在第 1 节已经阐述过,详细看int_register_android_os_BinderInternal()

frameworks/base/core/jin/android_util_Binder.cppstatic const JNINativeMethod gBinderInternalMethods[] = {/* name, signature, funcPtr */{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },...}
};
static int int_register_android_os_BinderInternal(JNIEnv* env)
{...return RegisterMethodsOrDie(
env, kBinderInternalPathName,gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

通过注册 gBinderInternalMethods 数组得知,最终调用接口android_os_BinderInternal_getContextObject():

frameworks/base/core/jin/android_util_Binder.cppstatic jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{sp<IBinder> b = ProcessState::self()->getContextObject(NULL);return javaObjectForIBinder(env, b);
}

这里很熟悉了,获取的是 context 为 0 的servicemanager 的BpBinder,并将BpBinder 通过函数javaObjectForIBinder() 转换成Java 的 BinderProxy 对象返回。

2.1.1 javaObjectForIBinder()

frameworks/base/core/jin/android_util_Binder.cppjobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{...BinderProxyNativeData* nativeData = new BinderProxyNativeData();nativeData->mOrgue = new DeathRecipientList;nativeData->mObject = val;jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());if (env->ExceptionCheck()) {// In the exception case, getInstance still took ownership of nativeData.return NULL;}...return object;
}

这里主要通过CallStaticObjectMethod() 调用BinderProxy 中的 geInstance(),而这里的全局对象 gBinderProxyOffsets 是在 int_register_android_os_BinderProxy() 中指定的:

frameworks/base/core/jin/android_util_Binder.cppstatic int int_register_android_os_BinderProxy(JNIEnv* env)
{gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));gErrorOffsets.mOutOfMemory =MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));gErrorOffsets.mStackOverflow =MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));jclass clazz = FindClassOrDie(env, kBinderProxyPathName);gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance","(JJ)Landroid/os/BinderProxy;");gBinderProxyOffsets.mSendDeathNotice =GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice","(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");clazz = FindClassOrDie(env, "java/lang/Class");gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");return RegisterMethodsOrDie(env, kBinderProxyPathName,gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

javaObjectForIBinder() 需要通过 CallStaticObjectMethod() 函数调用 BinderProxy 的 getInstance() 接口,来看下:

frameworks/base/core/java/android/os/BinderProxy.javaprivate static BinderProxy getInstance(long nativeData, long iBinder) {BinderProxy result;synchronized (sProxyMap) {try {result = sProxyMap.get(iBinder);if (result != null) {return result;}result = new BinderProxy(nativeData);} catch (Throwable e) {...}...}return result;}

至此,可知 BidnerInternal.getcontextObject() 获取的是context 为0 的 BinderProxy 对象。

2.2 ServiceManagerNative.asInterface()

framworks/base/core/java/android/os/ServiceManagerNative.javapublic static IServiceManager asInterface(IBinder obj) {if (obj == null) {return null;}// ServiceManager is never localreturn new ServiceManagerProxy(obj);}

BinderProxy 对象获取到后,通过asInterface,创建ServiceManager 的Java 端代理ServiceManagerProxy:

framworks/base/core/java/android/os/ServiceManagerNative.javaclass ServiceManagerProxy implements IServiceManager {public ServiceManagerProxy(IBinder remote) {mRemote = remote;mServiceManager = IServiceManager.Stub.asInterface(remote);}...public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)throws RemoteException {mServiceManager.addService(name, service, allowIsolated, dumpPriority);}...private IBinder mRemote;private IServiceManager mServiceManager;
}

mRemote 为BinderProxy 对象,mServiceManager 则是所有接口的入口,ServiceManager的真正proxy,下面会继续分析。

3. ServiceManager.addService()

通过第 2 节,我们得知,Java 端进行binder 通信,可能是client 通过ServiceManager.getService() 获取到的server 代理,也可能是server 端通过ServiceManager.addService() 将service 注册到ServiceManager 中。但无论哪个接口,都是通过ServiceManager 在java 端的代码 BinderProxy 进行操作的。

这一节分析下addService():

frameworks/base/core/java/android/os/ServiceManager.java public static void addService(String name, IBinder service, boolean allowIsolated,int dumpPriority) {try {getIServiceManager().addService(name, service, allowIsolated, dumpPriority);} catch (RemoteException e) {Log.e(TAG, "error in addService", e);}}

getIServiceManager() 就是上面第 2.2 节返回的ServiceManagerProxy 对象,如果上面 2.2 节代码所示,addService() 最终调用的是 mServiceManager.addService(),而这个mServiceManager 则是将上文讲到的context 0 的BinderProxy 对象作为参数带入通过IServiceManager 获取的代理:

 mServiceManager = IServiceManager.Stub.asInterface(remote);

继续分析。

通常andorid 都会将 *.aidl 文件编译成对应的 java 文件,而最终的 java 源码是在out/soong/.intermediates/ 下,详细看本系列文章中的第七篇:Java 下的C-S

aidl 编译后的JAVA 文件都会最终打包到aidl*.srcjar 中,那具体的文件怎么确定呢?需要依赖frameworks 文件夹或者system 文件夹的 *.aidl.d 文件。

如果aidl 文件是定义在frameworks 下,那么就可以到framework 下对应的目录查找对应的 *.aidl.d 文件。

这个的 IServiceManager 就是 IServiceManager.aidl 编译后的类名

      @Override public void addService(java.lang.String name, android.os.IBinder service, boolean allowIsolated, int dumpPriority) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeStrongBinder(service);...boolean _status = mRemote.transact(Stub.TRANSACTION_addService, _data, _reply, 0);if (!_status && getDefaultImpl() != null) {getDefaultImpl().addService(name, service, allowIsolated, dumpPriority);return;}_reply.readException();}...}

proxy 的代码比较简单:

  • 通过接口writeStrongBinder() 将需要添加的 service 写到 Parcel 中;
  • 通过mRemote.transact() 进行通信,确认是否达到addService() 目的;
  • 如果上面失败,则尝试通过 getDefaultImpl() 进行 addService();

通常是走第二步,第三步的default impl 需要通过接口 setDefaultImpl() 指定。

通过第 2.2 节获悉,mRemote 就是ServiceManager 的java 端BinderProxy 对象。

3.1 writeStrongBinder()

frameworks/base/core/java/android/os/Parcel.javapublic final void writeStrongBinder(IBinder val) {nativeWriteStrongBinder(mNativePtr, val);}

JNI 接口位于android_os_Parcel.cpp 中,而此接口也是在zygote 启动是加载。这里不过多分析,详细请查看 AndroidRuntime.cpp 中数组 gRegJNI 里的成员 register_android_os_Parcel。

最终调用到JNI android_os_Parcel_writeStrongBinder():

frameworks/base/core/jni/android_os_Parcel.cppstatic void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);if (parcel != NULL) {const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));if (err != NO_ERROR) {signalExceptionForError(env, clazz, err);}}
}

来看下核心的 ibinderForJavaObject():

frameworks/base/core/jni/android_util_Binder.cppsp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{if (obj == NULL) return NULL;// Instance of Binder?if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {JavaBBinderHolder* jbh = (JavaBBinderHolder*)env->GetLongField(obj, gBinderOffsets.mObject);return jbh->get(env, obj);}// Instance of BinderProxy?if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {return getBPNativeData(env, obj)->mObject;}ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);return NULL;
}

纯正的service 属于 Binder 类型,所以匹配时与gBinderOffsets.mClass 匹配,该变量是也是在注册的时候赋值,详细看 int_register_android_os_Binder()

gBinderOffsets.mObject 获取的是 Binder.java 中的 mObject 对象(详细看int_register_android_os_Binder函数),也就是在Binder 构造时,从native 获取的 BBinderHolder 指针:

frameworks/base/core/java/android/os/Binder.javapublic Binder(@Nullable String descriptor)  {mObject = getNativeBBinderHolder();...}

---->

frameworks/base/core/jni/android_util_Binder.cppstatic jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
{JavaBBinderHolder* jbh = new JavaBBinderHolder();return (jlong) jbh;
}

ibinderForJavaObject() 除了上面获取到的JavaBBinderHolder,最终就是通过该 holder 调用 get()接口,获取 servcie 的BBinder:

frameworks/base/core/jni/android_util_Binder.cppsp<JavaBBinder> get(JNIEnv* env, jobject obj){AutoMutex _l(mLock);sp<JavaBBinder> b = mBinder.promote();if (b == NULL) {b = new JavaBBinder(env, obj);...}return b;}

来看下JavaBBinder:

frameworks/base/core/jni/android_util_Binder.cppclass JavaBBinder : public BBinder
{...
}

所以,writeStrongBinder() 最终就是 native 中 BBinder 写入parcel 传入transact()。

3.2 BinderProxy.transact()

详细看第 5节

3.3 JavaBBinder.onTransact()

当Client 通过 transact() 进行通信时,最终 BBinder 会触发onTransact(),对于java service,最终触发的就是 JavaBBinder.onTransact()

frameworks/base/core/jni/android_util_Binder.cppstatus_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override{...jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

gBinderOffsets.mExecTransact 也是int_register_android_os_Binder() 赋值,调用的是Binder.java 中execTransact(),这里不过多阐述,最终调用stub.onTransact。

4. ServiceManager.getService()

同addService,getService 最终也是调用到IServiceManager中:

      @Override public android.os.IBinder checkService(java.lang.String name) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();android.os.IBinder _result;try {...boolean _status = mRemote.transact(Stub.TRANSACTION_checkService, _data, _reply, 0);if (!_status && getDefaultImpl() != null) {return getDefaultImpl().checkService(name);}_reply.readException();_result = _reply.readStrongBinder();}finally {_reply.recycle();_data.recycle();}return _result;}

同理addService(),这里会通过 _reply.readStrongBinder() 获得native 端传过来的binder 信息。

4.1 readStrongBinder()

最终会调用到JNI android_os_Parcel.cpp

frameworks/base/core/jni/android_os_Parcel.cppstatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);if (parcel != NULL) {return javaObjectForIBinder(env, parcel->readStrongBinder());}return NULL;
}

2.1 节已经分析过了,最终通过javaObjectForIBinder() 获取到 service 在java 端的BinderProxy 对象。

5. BinderProxy.transact()

frameworks/base/core/java/android/os/BinderProxy.javapublic boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");....try {return transactNative(code, data, reply, flags);} finally {...}}

其实这里核心就是调用transactNative:

frameworks/base/core/jni/android_util_Binder.cppstatic jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{...status_t err = target->transact(code, *data, reply, flags);...
}

接下来就是BpBinder->transact,看详细看本系列文章中的第三篇:service 注册

6. 总结

最后再来根据框架图进行总结:

  • Java client 通过getService() 获取service 的代理,getService() 最后会通过readStrongBinder() 获取 BinderProxy 对象;
  • Java client 通过transact 与service 通信,通过native 接口 transactNative() 调用到BpBinder;
  • Java service 通过addService() 注册,addService() 会通过writeStrongBinder() 调用native 接口注册到JNI;
  • Java service 注册时,会在JNI 中创建 JavaBBinderHolder,这里封装了与 native 通信的JavaBBinder,而JavaBBinder 就是继承自BBinder;
  • Java client 的调用对于 java service 最终会调用 onTransact(),并回调到java 端stub.onTransact();

Android Binder通信原理(五):Java 端的service 注册和获取相关推荐

  1. Android10.0 Binder通信原理(五)-Binder驱动分析

    摘要:本节主要来讲解Android10.0 Binder的驱动层分析 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计 ...

  2. Android10.0 Binder通信原理(十一)-Binder总结

    摘要:本节主要来讲解Android10.0 Binder的通信原理总结 阅读本文大约需要花费17分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...

  3. Android10.0 Binder通信原理(九)-AIDL Binder示例

    摘要:本节主要来讲解Android10.0 Binder中如何使用AIDL 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平 ...

  4. Android10.0 Binder通信原理(八)-Framework层分析

    摘要:本节主要来讲解Android10.0 Binder 在Framework的使用分析 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,An ...

  5. Android10.0 Binder通信原理(七)-Framework binder示例

    摘要:本节主要来讲解Android10.0 Binder在Framework中的示例 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andr ...

  6. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击

    摘要:本节主要来讲解Android10.0 Binder的数据是如何完成定向打击 阅读本文大约需要花费30分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...

  7. Android10.0 Binder通信原理(四)-Native-C\C++实例分析

    摘要:本节主要来讲解Android10.0 Binder的Native层实例流程 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...

  8. Android10.0 Binder通信原理(三)-ServiceManager篇

    摘要:本节主要来讲解Android10.0 Binder中守护进程ServiceManager是如何启动.注册.获取服务 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于A ...

  9. Android10.0 Binder通信原理(二)-Binder入门篇

    摘要:本节主要来讲解Android10.0 Binder的设计原理,如何设计一个Binder通信 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分 ...

最新文章

  1. 5G 产业链重要投资节点
  2. JS 获取字符串长度, 区别中英文
  3. Apache Hook机制解析(中)——细节讨论
  4. mysql plugin filed_MySQL启动时报Plugin 'InnoDB' registration as a STORAGE ENGINE failed.错误
  5. python:直接插入和简单选择排序
  6. Mybatis通过colliection属性递归获取菜单树
  7. rust怎么传送坐标_德国人怎么学电机——浅谈电机模型(十一):异步电机:绕线转子电机(一)...
  8. OpenCV3学习(11.2)LK光流法原理及opencv实现
  9. git(2)---git 分布式版本控制系统
  10. python-day02
  11. bert获得词向量_只需几行 Python 代码,即可用 BERT 玩转词嵌入!
  12. EPSON EPL-6200 无法网络共享问题
  13. 硬盘属于计算机主机吗,电脑主机换硬盘后还是不是原来的主机?
  14. 大数据hadoop培训总结
  15. android 下拉刷新 组件,Android实现简单的下拉刷新控件
  16. php短信接口怎么用,php短信接口接入详细过程
  17. 【安全牛学习笔记】拒绝服务攻击工具-NMAP、匿名者拒绝服务工具包(匿名者发布的DoS工具)、其他拒绝服务工具-XOIC、HULK、DDOSIM、GoldenEye
  18. 人工智能、大数据和云计算之间,它们之间主要有什么关系?
  19. 看看人家那系统设计做的,那叫一个优雅
  20. PTA 天梯赛 L1-7 天梯赛的善良 (20 分)

热门文章

  1. $emit自定义子组件和父组件通信
  2. Bugku—come_game
  3. 你的月薪等于多少个爽?(C语言实现)
  4. HDU 1006 Tick and Tick 解不等式解法
  5. org.apache.jasper.JasperException: 无法为JSP编译类:
  6. python 绘制等高线图导出dxf_在python上将dxf转换为bmp写入
  7. 损失函数(IoU、GIoU、DIoU、CIoU)
  8. I2C总线时序图: 8位设备地址 16位寄存器地址 16位数据
  9. WCF自定义授权[转自小庄的博客]
  10. 谈钱不丢人,但请实事求是