源码基于: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.cpp
static 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.cpp
int 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 manager
sServiceManager = 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.java
public static final native IBinder getContextObject();
这个需要调用 JNI 接口,而这个接口注册在第 1 节已经阐述过,详细看int_register_android_os_BinderInternal():
frameworks/base/core/jin/android_util_Binder.cpp
static 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.cpp
static 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.cpp
jobject 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.cpp
static 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.java
private 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.java
public static IServiceManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// ServiceManager is never local
return new ServiceManagerProxy(obj);
}
BinderProxy 对象获取到后,通过asInterface,创建ServiceManager 的Java 端代理ServiceManagerProxy:
framworks/base/core/java/android/os/ServiceManagerNative.java
class 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.java
public 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.cpp
static 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.cpp
sp<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.java
public Binder(@Nullable String descriptor) {
mObject = getNativeBBinderHolder();
...
}
---->
frameworks/base/core/jni/android_util_Binder.cpp
static 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.cpp
sp<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.cpp
class 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.cpp
status_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.cpp
static 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.java
public 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.cpp
static 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. 总结
文章来源:https://www.toymoban.com/news/detail-503464.html
最后再来根据框架图进行总结:文章来源地址https://www.toymoban.com/news/detail-503464.html
- 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 注册和获取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!