public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);//1
data.writeInt(allowIsolated ? 1 : 0);
data.writeInt(dumpPriority);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//2
reply.recycle();
data.recycle();
}
注释1处的data.writeStrongBinder很关键,后续会进行分析。这里又看到了Parcel,它是一个数据包装器,将请求数据写入到Parcel类型的对象data中,通过注释1处的mRemote.transact发送出去,mRemote实际上是BinderProxy,BinderProxy.transact是native函数,实现的函数如下所示。
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
{
if (dataObj == NULL) {
jniThrowNullPointerException(env, NULL);
return JNI_FALSE;
}
Parcel* data = parcelForJavaObject(env, dataObj);//1
if (data == NULL) {
return JNI_FALSE;
}
Parcel* reply = parcelForJavaObject(env, replyObj);//2
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
IBinder* target = getBPNativeData(env, obj)->mObject.get();//3
if (target == NULL) {
jniThrowException(env, “java/lang/IllegalStateException”, “Binder has been finalized!”);
return JNI_FALSE;
}
…
status_t err = target->transact(code, *data, reply, flags);//4
return JNI_FALSE;
}
注释1和注释2处,将Java层的Parcel对象转化成为Native层的Parcel对象。在1.1小节中,我们得知BpBinder会保存到BinderProxy的成员变量mObject中,因此在注释3处,从BinderProxy的成员变量mObject中获取BpBinder。最终会在注释4处调用BpBinder的transact函数,向Binder驱动发送数据,可以看出Java Binder是需要Native Binder支持的,最终的目的就是向Binder驱动发送和接收数据。
接着回过头来分析1.3小节遗留下来的data.writeStrongBinder(service),代码如下所示。
frameworks/base/core/java/android/os/Parcel.java
public final void writeStrongBinder(IBinder ll) {
nativeWriteStrongBinder(mNativePtr, val);
}
nativeWriteStrongBinder是Native方法,实现的函数为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
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));//1
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
接着查看注释1处ibinderForJavaObject函数:
frameworks/base/core/jni/android_util_Binder.cpp
sp ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//1
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh->get
(env, obj);//2
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return getBPNativeData(env, obj)->mObject;
}
ALOGW(“ibinderForJavaObject: %p is not a Binder object”, obj);
return NULL;
}
注释2处,如果obj是Java层的BinderProxy类,则返回BpBinder。
注释1处,如果obj是Java层的Binder类,那么先获取JavaBBinderHolder对象,然后在注释2处调用JavaBBinderHolder的get函数,代码如下所示。
frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder
class JavaBBinderHolder
{
public:
sp get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp b = mBinder.promote();//1
if (b == NULL) {
//obj是一个Java层Binder对象
b = new JavaBBinder(env, obj);//2
mBinder = b;
ALOGV(“Creating JavaBinder %p (refs %p) for Object %p, weakCount=%” PRId32 “\n”,
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
sp getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp mBinder;
};
成员变量mBinder是wp
类型的弱引用,在注释1处得到sp
类型的强引用b,在注释2处创建JavaBBinder并赋值给b。那么,JavaBBinderHolder的get函数返回的是JavaBBinder。
data.writeStrongBinder(service)在本文中等价于:
data.writeStrongBinder(new JavaBBinder(env,Binder))。
讲到这里可以得知ServiceManager.addService()传入的并不是AMS本身,而是JavaBBinder。
接着来分析JavaBBinder,查看它的构造函数:
frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject /* Java Binder */ c)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV(“Creating JavaBBinder %p\n”, this);
gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
gcIfManyNewRefs(env);
}
…
可以发现JavaBBinder继承了BBinder,那么JavaBBinder的作用是什么呢?当Binder驱动得到客户端的请求,紧接着会将响应发送给JavaBBinder,这时会调用JavaBBinder的onTransact函数,代码如下所示。
frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
ALOGV(“onTransact() on %p calling object %p in env %p vm %p\n”, this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast(&data), reinterpret_cast(reply), flags);//1
…
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
在注释1处会调用Java层Binder的execTransact函数:
frameworks/base/core/java/android/os/Binder.java
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
…
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + “:” + code);
}
res = onTransact(code, data, reply, flags);//1
} catch (RemoteException|RuntimeException e) {
…
}
…
return res;
}
关键点是注释1处的onTransact函数,AMS实现了onTransact函数,从而完成业务实现。
从这里可有看出,JavaBBinder并没有实现什么业务,当它接收到请求时,会调用Binder类的execTransact函数,execTransact函数内部又调用了onTransact函数,系统服务会重写onTransact函数来实现自身的业务功能。
Binder架构如下图所示。
Native Binder的部分在此前的文章已经讲过,这里主要来说说Java Binder部分,从图中可以看到:
1.Binder是服务端的代表,JavaBBinder继承BBinder,JavaBBinder通过mObject变量指向Binder。
2.BinderProxy是客户端的代表,ServiceManager的addService等方法会交由ServiceManagerProxy处理。
3.ServiceManagerProxy的成员变量mRemote指向BinderProxy对象,所以ServiceManagerProxy的addService等方法会交由BinderProxy来处理。
4.BinderProxy的成员变量mObject指向BpBinder对象,因此BinderProxy可以通过BpBinder和Binder驱动发送数据。
感谢
《深入理解Android卷二》
《深入理解Android卷三》
http://gityuan.com/2015/11/21/binder-framework/
千里之行始于足下 。
Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。
我把自己这段时间整理的Android最重要最热门的学习方向资料放在了我的GitHub:https://github.com/xieyuliang/Android-P7-(点击蓝色字体可以获取),里面还有不同方向的自学编程路线、面试题集合/面经、及系列技术文章等。
资源持续更新中,欢迎大家一起学习和探讨。
的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。
我把自己这段时间整理的Android最重要最热门的学习方向资料放在了我的GitHub:https://github.com/xieyuliang/Android-P7-(点击蓝色字体可以获取),里面还有不同方向的自学编程路线、面试题集合/面经、及系列技术文章等。
资源持续更新中,欢迎大家一起学习和探讨。