Android Binder进程间通信 Java接口源代码
一、架构代码:
~/Android/frameworks/base/core/java/android/os
----IInterface.java (Interface)
----IServiceManager.java (IServiceManager)
----IBinder.java (IBinder)
----Binder.java (BinderProxy,Binder)
----ServiceManagerNative.java (ServiceManagerProxy,ServiceManagerNative)
----ServiceManager.java (ServiceManager)
~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
测试代码:(参考实现硬件访问服务和开发Android应用程序来使用硬件访问服务两篇文章)
~/Android/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os
----IFregService.java
~/Android/frameworks/base/services/java/com/android/server
----FregService.java
~/Android/packages/experimental/Freg
----src----shy/luo/freg----Freg.java
uml类图如下:


二、源码分析
系统进程System启动了硬件访问服务FregService,如下:
~/android-2.3_r1/frameworks/base/services/java/com/android/server
----SystemServer.java
@Override public void run() { .................................................................................... ....... try { Slog.i(TAG, "Freg Service"); ServiceManager.addService("freg", new FregService()); } catch (Throwable e) { Slog.e(TAG, "Failure starting Freg Service", e); } 调用了ServiceManager的addService方法,实现如下:~/Android/frameworks/base/core/java/android/os
----ServiceManager.java
<pre name="code" class="java">public final class ServiceManager { ...... private static IServiceManager sServiceManager; ...... private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; } ...... public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } ...... }1、System进程,获取Service Manager的Java远程接口的过程
如果其静态成员变量sServiceManager尚未创建,那么就调用ServiceManagerNative.asInterface函数来创建。在调用ServiceManagerNative.asInterface函数之前,首先要通过BinderInternal.getContextObject函数来获得一个BinderProxy对象。
我们来看一下BinderInternal.getContextObject的实现: ~/Android/frameworks/base/core/java/com/android/internal/os
----BinderInternal.java
public class BinderInternal { ...... /** * Return the global "context object" of the system. This is usually * an implementation of IServiceManager, which you can use to find * other services. */ public static final native IBinder getContextObject(); ...... }这里可以看出,BinderInternal.getContextObject是一个JNI方法,实现如下:
~/Android/frameworks/base/core/jni
----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); } 这里看到我们熟悉的ProcessState::self()->getContextObject函数,返回一个BpBinder对象,它的句柄值是0,即下面语句: sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 相当于是:sp<IBinder> b = new BpBinder(0);
在调用javaObjectForIBinder函数之前,我们先介绍jni的加载。

先来看两个变量gBinderOffsets和gBinderProxyOffsets的定义。
先看gBinderOffsets的定义:
~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
static struct bindernative_offsets_t { // Class state. jclass mClass; jmethodID mExecTransact; // Object state. jfieldID mObject; } gBinderOffsets;简单来说,gBinderOffsets变量是用来记录上面第二个类图中的Binder类的相关信息的,它是在注册Binder类的JNI方法的int_register_android_os_Binder函数初始化的:
~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
const char* const kBinderPathName = "android/os/Binder"; static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz; clazz = env->FindClass(kBinderPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder"); gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);//引用java层的Binder类 gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z");//引用java层Binder类的execTransact方法 assert(gBinderOffsets.mExecTransact); gBinderOffsets.mObject = env->GetFieldID(clazz, "mObject", "I");//引用java层Binder类的mObject属性 assert(gBinderOffsets.mObject); return AndroidRuntime::registerNativeMethods( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); } 再来看gBinderProxyOffsets的定义:~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
static struct binderproxy_offsets_t { // Class state. jclass mClass; jmethodID mConstructor; jmethodID mSendDeathNotice; // Object state. jfieldID mObject; jfieldID mSelf; } gBinderProxyOffsets; 简单来说,gBinderProxyOffsets是用来变量是用来记录上面第一个图中的BinderProxy类的相关信息的,它是在注册BinderProxy类的JNI方法的int_register_android_os_BinderProxy函数初始化的:~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
const char* const kBinderProxyPathName = "android/os/BinderProxy"; static int int_register_android_os_BinderProxy(JNIEnv* env) { jclass clazz; .......... clazz = env->FindClass(kBinderProxyPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy"); gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);//引用了BinderProxy类 gBinderProxyOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V");//引用BinderProxy类的构造函数 ..... gBinderProxyOffsets.mSendDeathNotice = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");//引用了BinderProxy类的sendDeathNotice方法 ..... gBinderProxyOffsets.mObject = env->GetFieldID(clazz, "mObject", "I");//引用了BinderProxy类的mObject属性 ..... gBinderProxyOffsets.mSelf = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");//引用了BinderProxy类的mSelf属性 ...... return AndroidRuntime::registerNativeMethods( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); }再来看gWeakReferenceOffsets的定义:
~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
static struct weakreference_offsets_t { jclass mClass; jmethodID mGet; } gWeakReferenceOffsets; gWeakReferenceOffsets同样是在函数int_register_android_os_BinderProxy中初始化,如下所示:~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
const char* const kBinderProxyPathName = "android/os/BinderProxy"; static int int_register_android_os_BinderProxy(JNIEnv* env) { jclass clazz; clazz = env->FindClass("java/lang/ref/WeakReference"); ...... gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);//引用了WeakReference类 gWeakReferenceOffsets.mGet = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");//引用了WeakReference类的get方法 ...... ......... return AndroidRuntime::registerNativeMethods( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); } 下面开始介绍javaObjectForIBinder,将这个BpBinder对象转换成一个BinderProxy对象:~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
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(); ........ return object; } // For the rest of the function we will hold this lock, to serialize // looking/creation of Java proxies for native Binder proxies. AutoMutex _l(mProxyLock); // Someone else's... do we know about it? jobject object = (jobject)val->findObject(&gBinderProxyOffsets);//检查当前进程之前是否已经为它创建过一个BinderProxy对象 if (object != NULL) {//如果有返回来的就是一个指向该BinderProxy对象的WeakReference对象object,即一个弱引用对象 jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);//由于弱引用对象object所指向的BinderProxy对象可能已经失效,因此,需要检查它的有效性,方法是调用它的成员函数get来获得一个强引用对象。 if (res != NULL) {//如果不为NULL ...... return res;//直接返回 } ..... android_atomic_dec(&gNumProxyRefs);//如果为NULL val->detachObject(&gBinderProxyOffsets);//解除它与一个无效的BinderProxy对象的对应关系 env->DeleteGlobalRef(object);//删除弱引用对象的全局引用 } object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);//创建一个BinderProxy对象 if (object != NULL) { ....... env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());//BinderProxy.mObject成员变量记录了这个BpBinder对象的地址 val->incStrong(object); // 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内部的成员变量mSelf(BinderProxy的弱引用对象),接着再创建一个全局引用对象来引用它 val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup);//把它放到BpBinder里面去,下次就要使用时,就可以在上一步调用BpBinder::findObj把它找回来了 // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object; } Binder代理对象的成员函数checkSubclass来指向的是一个Binder代理对象,还是一个JavaBBinder对象。Binder代理对象的成员函数checkSubclass是由其父类IBinder来实现的,如下所示:
~/Android/base/libs/binder
----Binder.cpp
bool IBinder::checkSubclass(const void* /*subclassID*/) const { return false; } BpBinder类的findObject,detachObject,attachObject,这里均不详细介绍,详情请看《Android系统源代码情景分析》,作者罗升阳。执行完javaObjectForIBinder,先返回到BinderInternal类的静态成员函数getContextObject中,接着又返回ServiceManager类的静态成员函数getIServiceManager中,
这时候已经获得了一个BinderProxy对象,就下来就调用ServiceManagerNative类的静态成员函数asInterface将它封装成一个ServiceManagerProxy对象了。
ServiceManagerNative类的静态成员函数asInterface的实现如下:
~/Android/frameworks/base/core/java/android/os
----ServiceManagerNative.java
public abstract class ServiceManagerNative ...... { ...... static public IServiceManager asInterface(IBinder obj)//BinderProxy { if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ServiceManagerProxy(obj);//创建Service Manager的java代理对象 } ...... } 返回到ServiceManager.getIServiceManager中,从下面语句返回:sServiceManager = ServiceManagerNative.asInterface(new BinderProxy()); 相当于: sServiceManager = new ServiceManagerProxy(new BinderProxy()); 2、System进程,封装进程间通信数据
下面该执行: getIServiceManager().addService(name, service); //name为freg,service为new FregService() 我们先来看一下FregService的创建过程: new FregService(); 这个语句会调用FregService类的构造函数,而FregService类继承于IFregService.Stub类,IFregService.Stub类又继承了Binder类,因此,最后会调用Binder类的构造函数:
~/Android/frameworks/base/core/java/android/os
----Binder.java
public class Binder implements IBinder { ...... private int mObject; ...... public Binder() { init(); ...... } private native final void init(); ...... } 这里调用了一个JNI方法init来初始化这个Binder对象,实现如下:~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
static void android_os_Binder_init(JNIEnv* env, jobject clazz) { JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);//创建一个JavaBBinderHolder对象jbh .... jbh->incStrong(clazz); env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);//把这个对象的地址保存在上面的Binder类的mObject成员变量中 } 它实际上只做了一件事情,就是创建一个JavaBBinderHolder对象jbh,然后把这个对象的地址保存在上面的Binder类的mObject成员变量中,后面我们会用到。开始执行:
getIServiceManager().addService(name, service); //name为freg,service为new FregService() 这里的getIServiceManager函数我们在前面已经分析过了,它返回的是一个ServiceManagerProxy对象的IServiceManager接口。因此,我们进入到ServiceManagerProxy.addService中去看看:~/Android/frameworks/base/core/java/android/os
----ServiceManagerNative.java
class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy(IBinder remote) { mRemote = remote; } ...... public void addService(String name, IBinder service) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor);//android.os.IServiceManager data.writeString(name);//freg data.writeStrongBinder(service);//new FregService() mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); } ...... private IBinder mRemote; } 这里我们关注是如何把参数service写到data这个Parcel对象中去的:data.writeStrongBinder(service); 我们来看看Parcel.writeStrongBinder函数的实现:
public final class Parcel { ...... /** * Write an object into the parcel at the current dataPosition(), * growing dataCapacity() if needed. */ public final native void writeStrongBinder(IBinder val);//new FregService() ...... } 这里的writeStrongBinder函数又是一个JNI方法,实现如下:
~/Android/frameworks/base/core/jni
----android_util_Binder.cpp
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)//clazz为Parcel,object为new FregService() { Parcel* parcel = parcelForJavaObject(env, clazz);//获取java层Parcel对象data的引用 if (parcel != NULL) { const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); if (err != NO_ERROR) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); } } } ibinderForjavaObject实现如下:~/Android/frameworks/base/core/jni
----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->GetIntField(obj, gBinderOffsets.mObject);//这里把obj对象的mObject成员变量强制转为JavaBBinderHolder对象 return jbh != NULL ? jbh->get(env) : NULL; } if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); } LOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; } 在前面创建FregService对象,曾经在调用到FregService的父类Binder中,曾经在JNI层创建了一个JavaBBinderHolder对象,然后把这个对象的地址保存在Binder类的mObject成员变量中,因此,这里把obj对象的mObject成员变量强制转为JavaBBinderHolder对象。到了这里,这个函数的功课还未完成,还剩下最后关键的一步: return jbh != NULL ? jbh->get(env) : NULL; 先来看一下JavaBBinderHolder类的get函数的实现: class JavaBBinderHolder : public RefBase { ...... JavaBBinderHolder(JNIEnv* env, jobject object) : mObject(object) { ...... } ...... sp<JavaBBinder> get(JNIEnv* env) { AutoMutex _l(mLock); sp<JavaBBinder> b = mBinder.promote(); if (b == NULL) { b = new JavaBBinder(env, mObject); mBinder = b; ...... } return b; } ...... jobject mObject; wp<JavaBBinder> mBinder; }; 未完。
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://www.juheyunku.com/jiaob/android/9913.shtml
相关文章
热门TAG
命令 权重 外链 企业网站 白帽 php 织梦教程 dedecms修改内容 javascript 织梦 功能 标签 调用 详解 服务器 网站流量 实例解析 Dedecms 织梦cms HTML tags标签 python jquery教程 jquery windows SEO优化 蜘蛛 搜索引擎 网站收录 JSP最新文章
-
Android开发_深入学习ViewP
时间:2020-12-27
-
Android Binder进程间通信 J
时间:2020-12-27
-
50个Android开发技巧11 为文
时间:2020-12-27
-
处女男学Android(十二)
时间:2020-12-27
-
手把手教你用ViewPager自定
时间:2020-12-27
-
字母条索引定位
时间:2020-12-27
-
OGEngine教程:声音加载
时间:2020-12-27
-
Notification详解
时间:2020-12-27
热门文章
-
字母条索引定位
时间:2020-12-27
-
Notification详解
时间:2020-12-27
-
OGEngine教程:声音加载
时间:2020-12-27
-
处女男学Android(十二) Android菜单(Men
时间:2020-12-27
-
Android Binder进程间通信 Java接口源代码
时间:2020-12-27
-
50个Android开发技巧11 为文字添加特效
时间:2020-12-27
-
Android开发_深入学习ViewPager控件
时间:2020-12-27
-
手把手教你用ViewPager自定义实现Banner轮播
时间:2020-12-27
