Java层的ServiceManager和Native层的ServiceManager的对应过程
2017-01-12 15:22
225 查看
几天前一个同事问Java层的Binder和Java层的ServiceManager和C++层的ServiceManager是如何对应起来的,竟然一时语噻,一段时间不关注就会感到陌生啊,现在再总结一下,只写Java层的,C++层的不写,C++ Binder的知识需掌握,java和native的基本概念及对应关系不讲。
AppRuntime是AndroidRuntime的子类,它本身没有覆盖start方法,所以要去看AndroidRuntime类中的start方法
gRegJNI是个数组:
REG_JNI是一个宏定义
gRegJNI是一个RegJNIRec的数组,所以gRegJNI的定义就变成了这样:
register_jni_procs函数如下:
就是循环调用gRegJNI数组中的函数,这时register_android_os_Binder(env)就被调用了。
register_android_os_Binder在AndroidRuntime.cpp中被声明为extern:
实现它的地方是在android_util_Binder.cpp中:
从名字上看,它要关联3个Java的类,分别是Binder, BinderInternal和BinderProxy,一个一个看来:
关联了android.os.Binder类,并会用到该类的mExecTransact域和execTransact方法,将其保存到gBinderOffsets对象中,也就意味着native会将某值保存到mExecTransact中,也会回调execTransact方法。
关联了java的com.android.internal.os.BinderInternal类,保存了其forceBinderGc方法。
这个方法比较长,保存的Java的东西也比较多,值得注意的是,它还保存了BinderProxy的构造函数,也就是说它可能会主动new一个BinderProxy实例出来。
看到目前为止,native的Binder要对应到Java的3个类中,分别是android.os.Binder,com.android.internal.os.BinderInternal和android.os.BinderProxy。为了方便阅读,将它们的对应关系以类图的形式总结下:
以PackageManagerService为例:
getIServiceManager返回的是一个IServiceManager类,且是个单例,最后调用的就是
以上代码带来 三个问题,一个是BinderInternal.getContextObject(),一个是ServiceManagerNative.asInterface,另一个是addService的作用:
首先判断下和Java层关联的Native层的BpBinder是否存在,如果存在,删除。
接着创建一个Java层的BinderProxy实例。
将Native层的BpBinder指针保存到java BinderProxy实例的mObject字段中,这样通过BinderProxy的mObject字段就可以操作Native层的BpBinder了。
原子增加gNumProxyRefs和gNumRefsCreated的数量,当gNumRefsCreated的值超过200,将会调用BinderInternal的forceBinderGc方法。
总结下:
创建了一个Native层的BpBinder;
将BpBinder的指针保存到BinderProxy的mObject,而BpBinder的通信对象就是Native的ServiceManager,这为Java和Native的ServiceManager的通信埋下了伏笔。
可以将BinderProxy说成Java层的Bp端。
obj是Native实例化的BinderProxy对象,BinderProxy的代码在Binder.java中,和Binder位于同一个文件中。queryLocalInterface的返回值为null。
实例化一个ServiceManagerProxy对象,该实例中有一个IBinder类型的mRemote字段,该字段保存BinderProxy实例。
总结:
ServiceManagerNative.asInterface返回的是ServiceManagerProxy的实例,该实例实现IServiceManager的接口。
ServiceManagerProxy中通过mRemote字段保存了BinderProxy,也就是Java层的Bp端。
mRemote即为BinderProxy,它会调用transactNative,transactNative是个native方法,接着看这个方法。
取出保存在BinderProxy中的BpBinder对象的指针
向Native层的ServiceManager发送请求
总结:
Java层调用ServiceManger.addService后,最终是向Native层的ServiceManager请求增加服务的。
Native层的ServiceManager是只有一个的,而java层的ServiceManager相对于Native的ServiceManager也只是个C端,这样,不管是通过Native add service还是通过java add service,整个Android都可以拿到这个service的Binder。
addService第二个参数的类型是IBinder,它是个接口,而它的实现类是Binder,java上层能调用addService添加服务时,所有的实例都是Binder,根据java的规则,只要实例化,其父类的相应的构造函数必被调用:
init()是native方法,其实现在android_util_Binder.cpp中:
new一个native层的JavaBBinderHolder,并将其保存到Binder的mObject中。注意哦,虽然native层的gBinderOffsets.mObject是个static的,但java层的Binder的mObject可不是static的哦,就是说每个Binder实例都有一个Native的JavaBBinderHolder对象指针。
JavaBBinderHolder类的声明如下:
没有继承BBinder,还是没发现作为Bn端的踪影,需要再review下前面的流程,看下ServiceManagerProxy添加服务时发生了什么:
writeStrongBinder值得怀疑
nativeWriteStrongBinder的实现在android_os_Parcel.cpp中:
调用了一个ibinderForJavaObject函数,该函数位于android_util_Binder.cpp中
传入的obj是Binder实例,所以刚刚创建的JavaBBinderHolder的get函数会被调用:
返回的是JavaBBinder实例,
JavaBBinder继承了BBinder,所以最终添加到Native ServiceManager中的是这个对象,总结下它们的类图:
Java层的Binder对象拥有Native JavaBBinderHolder对象的指针,JavaBBinderHolder有JavaBBinder的,而JavaBBinder又有Java层Binder的对象。
Java层Binder的初始化过程
Binder最终是要和它的驱动打交道,Java层要调Linux内核层的东西必然要通过native方法,而对于android的系统服务,native和java的对应,总会有一个注册过程,先看这个注册是在哪实现的JNI Binder的注册
Zygote在启动时:app_main.cpp int main(int argc, char* const argv[]) { ...... AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); ...... if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } ...... }
AppRuntime是AndroidRuntime的子类,它本身没有覆盖start方法,所以要去看AndroidRuntime类中的start方法
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { ...... /* * Register android functions. */ if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } ...... } /* * Register android native functions with the VM. */ /*static*/ int AndroidRuntime::startReg(JNIEnv* env) { ...... if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { env->PopLocalFrame(NULL); return -1; } ...... }
gRegJNI是个数组:
static const RegJNIRec gRegJNI[] = { ...... REG_JNI(register_android_os_Binder), ...... };
REG_JNI是一个宏定义
#ifdef NDEBUG #define REG_JNI(name) { name } struct RegJNIRec { int (*mProc)(JNIEnv*); }; #else #define REG_JNI(name) { name, #name } struct RegJNIRec { int (*mProc)(JNIEnv*); const char* mName; }; #endif
gRegJNI是一个RegJNIRec的数组,所以gRegJNI的定义就变成了这样:
static const RegJNIRec gRegJNI[] = { ...... { register_android_os_Binder }, ...... };
register_jni_procs函数如下:
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env) { for (size_t i = 0; i < count; i++) { if (array[i].mProc(env) < 0) { #ifndef NDEBUG ALOGD("----------!!! %s failed to load\n", array[i].mName); #endif return -1; } } return 0; }
就是循环调用gRegJNI数组中的函数,这时register_android_os_Binder(env)就被调用了。
register_android_os_Binder在AndroidRuntime.cpp中被声明为extern:
extern int register_android_os_Binder(JNIEnv* env);
实现它的地方是在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; ...... return 0; }
从名字上看,它要关联3个Java的类,分别是Binder, BinderInternal和BinderProxy,一个一个看来:
const char* const kBinderPathName = "android/os/Binder"; static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz = FindClassOrDie(env, kBinderPathName); gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z"); gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); return RegisterMethodsOrDie( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); }
关联了android.os.Binder类,并会用到该类的mExecTransact域和execTransact方法,将其保存到gBinderOffsets对象中,也就意味着native会将某值保存到mExecTransact中,也会回调execTransact方法。
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)); }
关联了java的com.android.internal.os.BinderInternal类,保存了其forceBinderGc方法。
const char* const kBinderProxyPathName = "android/os/BinderProxy"; static int int_register_android_os_BinderProxy(JNIEnv* env) { jclass clazz = FindClassOrDie(env, "java/lang/Error"); gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 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"); gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf", "Ljava/lang/ref/WeakReference;"); gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J"); clazz = FindClassOrDie(env, "java/lang/Class"); gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;"); return RegisterMethodsOrDie( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); }
这个方法比较长,保存的Java的东西也比较多,值得注意的是,它还保存了BinderProxy的构造函数,也就是说它可能会主动new一个BinderProxy实例出来。
看到目前为止,native的Binder要对应到Java的3个类中,分别是android.os.Binder,com.android.internal.os.BinderInternal和android.os.BinderProxy。为了方便阅读,将它们的对应关系以类图的形式总结下:
将Java层的服务注册到ServiceManager中的过程
我们知道,native层的Binder有Bn和Bp之说,Bn应该是Binder Native的缩写,就是本地实现Binder的意思也可以说是C/S中的S,Bp是Binder Proxy的缩写,相当于C。以PackageManagerService为例:
public static PackageManagerService main(Context ...... PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore); ...... ServiceManager.addService("package", m); return m; }
public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } }
getIServiceManager返回的是一个IServiceManager类,且是个单例,最后调用的就是
private static IServiceManager getIServiceManager() { if (sServiceManager != < ee7b span class="hljs-keyword">null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
以上代码带来 三个问题,一个是BinderInternal.getContextObject(),一个是ServiceManagerNative.asInterface,另一个是addService的作用:
BinderInternal.getContextObject()的实质
ServiceManagerNative.asInterface中的参数是BinderInternal.getContextObject(),看它是native方法,对应的native代码就在刚刚看到的android_util_Binder.cpp文件中:static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { // 是一个BpBinder sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); }
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; if (val->checkSubclass(&gBinderOffsets)) { // 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? // 1 jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (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); } //2 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. //3 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)); ...... // Note that a new object reference has been created. //4 android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object; }
首先判断下和Java层关联的Native层的BpBinder是否存在,如果存在,删除。
接着创建一个Java层的BinderProxy实例。
将Native层的BpBinder指针保存到java BinderProxy实例的mObject字段中,这样通过BinderProxy的mObject字段就可以操作Native层的BpBinder了。
原子增加gNumProxyRefs和gNumRefsCreated的数量,当gNumRefsCreated的值超过200,将会调用BinderInternal的forceBinderGc方法。
总结下:
创建了一个Native层的BpBinder;
将BpBinder的指针保存到BinderProxy的mObject,而BpBinder的通信对象就是Native的ServiceManager,这为Java和Native的ServiceManager的通信埋下了伏笔。
可以将BinderProxy说成Java层的Bp端。
ServiceManagerNative.asInterface的作用
static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } //1 IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //2 return new ServiceManagerProxy(obj); }
obj是Native实例化的BinderProxy对象,BinderProxy的代码在Binder.java中,和Binder位于同一个文件中。queryLocalInterface的返回值为null。
实例化一个ServiceManagerProxy对象,该实例中有一个IBinder类型的mRemote字段,该字段保存BinderProxy实例。
public ServiceManagerProxy(IBinder remote) { mRemote = remote; }
总结:
ServiceManagerNative.asInterface返回的是ServiceManagerProxy的实例,该实例实现IServiceManager的接口。
ServiceManagerProxy中通过mRemote字段保存了BinderProxy,也就是Java层的Bp端。
addService的作用
有上分析,当调用ServiceManager.addService时,实际上调用的是ServiceManagerProxy类中的addService,ServiceManagerProxy类位于ServiceManagerNative.java文件中。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); //1 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
mRemote即为BinderProxy,它会调用transactNative,transactNative是个native方法,接着看这个方法。
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, //1 IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; } //2 status_t err = target->transact(code, *data, reply, flags); ...... return JNI_FALSE; }
取出保存在BinderProxy中的BpBinder对象的指针
向Native层的ServiceManager发送请求
总结:
Java层调用ServiceManger.addService后,最终是向Native层的ServiceManager请求增加服务的。
Native层的ServiceManager是只有一个的,而java层的ServiceManager相对于Native的ServiceManager也只是个C端,这样,不管是通过Native add service还是通过java add service,整个Android都可以拿到这个service的Binder。
Java Service端的Bp在哪里
这时候还有个疑问,当调用ServiceManager.addService时传入的Service应该对应到Native的BnBinder啊,现在对应关系如何体现呢?这个关系要重看下addService了。addService第二个参数的类型是IBinder,它是个接口,而它的实现类是Binder,java上层能调用addService添加服务时,所有的实例都是Binder,根据java的规则,只要实例化,其父类的相应的构造函数必被调用:
public Binder() { init(); ...... }
init()是native方法,其实现在android_util_Binder.cpp中:
static void android_os_Binder_init(JNIEnv* env, jobject obj) { JavaBBinderHolder* jbh = new JavaBBinderHolder(); ... env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh); }
new一个native层的JavaBBinderHolder,并将其保存到Binder的mObject中。注意哦,虽然native层的gBinderOffsets.mObject是个static的,但java层的Binder的mObject可不是static的哦,就是说每个Binder实例都有一个Native的JavaBBinderHolder对象指针。
JavaBBinderHolder类的声明如下:
class JavaBBinderHolder : public RefBase { }
没有继承BBinder,还是没发现作为Bn端的踪影,需要再review下前面的流程,看下ServiceManagerProxy添加服务时发生了什么:
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { Parcel data = Parcel.obtain(); ...... data.writeStrongBinder(service); ...... }
writeStrongBinder值得怀疑
writeStrongBinder发生了什么
Parcel的这个函数如下:public final void writeStrongBinder(IBinder val) { nativeWriteStrongBinder(mNativePtr, val); }
nativeWriteStrongBinder的实现在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函数,该函数位于android_util_Binder.cpp中
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); return jbh != NULL ? jbh->get(env, obj) : NULL; } if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); } ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; }
传入的obj是Binder实例,所以刚刚创建的JavaBBinderHolder的get函数会被调用:
sp<JavaBBinder> get(JNIEnv* env, jobject obj) { AutoMutex _l(mLock); sp<JavaBBinder> b = mBinder.promote(); if (b == NULL) { b = new JavaBBinder(env, obj); mBinder = b; ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n", b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount()); } return b; }
返回的是JavaBBinder实例,
class JavaBBinder : public BBinder { }
JavaBBinder继承了BBinder,所以最终添加到Native ServiceManager中的是这个对象,总结下它们的类图:
Java层的Binder对象拥有Native JavaBBinderHolder对象的指针,JavaBBinderHolder有JavaBBinder的,而JavaBBinder又有Java层Binder的对象。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件