- 概述
- Service注册
- 获取service_manager代理
- Service的初始化
- addService
- Binder驱动调用Service
- 参考资料
概述
在上一节Binder 通信笔记(native)中,分析了在c++层service和client是怎样与binder驱动通信的。在Android中,绝大部分的应用和很多关键的系统Service是用Java来完成的。这一节,我们分析一下Java层程序是如何使用binder驱动进行通信的。其实Java层的binder通信是基于native的,它只是把binder的“网络层”(BpBinder和BBinder)做了一下封装,通过JNI将业务发送给了上一层。先看以下结构图
可以看到native层的类关系图和上一节下半部分完全相同,java层多了BinderProxy.class和Binder.class将native层的数据传送到上层。这一节我们只分析上半部分代码,下半部分的代码请查看上一节Binder 通信笔记(native)。
Service注册
这一节以ActivityManagerService为例,分析以下Java层Service注册到serviceManager的过程。ActivityManagerService是在SystemServer进程里面注册的,本节以分析binder为主,SystemServer的启动过程这里就不说了,网上有很多资料。大概流程是
SystemServer:main()
->run()
->startBootstrapServices()
->mActivityManagerService.setSystemProcess();
->ServiceManager.addService("activity", this, true);
下面看一下ServiceManager.addService的实现。
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
获取service_manager代理
在Java层有一个ServiceManager.class作为service_manager的代理,它是如何实现的呢,我们继续跟代码,看一下
getIServiceManager()
。
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
ServiceManager是一个单例实现,第一次初始化执行了
ServiceManagerNative.asInterface(BinderInternal.getContextObject())
。先看一下括号里吗的参数。
BinderInternal.getContextObject()
是一个native函数。它的实现在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(NULL);
上一篇博客已经分析过,它返回了BpBinder(0), 这个0就代表着远程为service_manager。继续看一下javaObjectForIBinder();
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
//1
if (val->checkSubclass(&gBinderOffsets)) {
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
AutoMutex _l(mProxyLock);
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
// 2
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);
}
//3
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.
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));
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
// Also remember the death recipients registered on this proxy
sp<DeathRecipientList> drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;
}
参数val为BpBinder(0),checkSubclass()函数使用IBinder里面的实现,直接返回false,所以1里的if为false。2里面是看一下是不是已经初始化过,直接进行返回,第一次引用是肯定为空,我们直接看3下面的代码。看代码之前先补充一下gBinderProxyOffsets。它是一个结构体,在jni进行init时
int_register_android_os_BinderProxy()
进行的初始化。看一下这个结构体,注释里是它值
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass; //android.os.BinderProxy
jmethodID mConstructor; //android.os.BinderProxy.<init>()
jmethodID mSendDeathNotice; //android.os.BinderProxy.sendDeathNotice()
// Object state.
jfieldID mObject; //android.os.BinderProxy.mObject
jfieldID mSelf; //android.os.BinderProxy.mSelf
jfieldID mOrgue; //android.os.BinderProxy.mOrgue
} gBinderProxyOffsets;
再分析javaObjectForIBinder第3段代码可以看出来是首先创建了一个BinderProxy的Java对象,并且把它的成员变量mObject指向BpBinder。同时BpBinder的持有BinderProxy,方便第二次调用时直接返回。
所以
BinderInternal.getContextObject()
返回的是BinderProxy对象。下面再看一下
ServiceManagerNative.asInterface
的实现
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
直接new一个ServiceManagerProxy返回。我们看一下他的类关系图
替换一下,
getIServiceManager()
就是
new ServiceManagerProxy(new BinderProxy())
。这样我们其实就是调用的ServiceManagerProxy的addService()函数。
Service的初始化
在分析addService()之前,我们需要先看一下ActivityManagerService的初始化过程,先看以下它的类关系图
ActivityManagerService的继承关系在上图中一目了然 。我们重点关注一下Binder的构造函数,在这里做了一些重要的初始化工作,在addService的时候会用到。Binder的初始化就是调用了一个init()函数,这个init()函数是一个 native函数,它的实现在android_util_Binder.cpp里面。
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
创建了一个JavaBBinderHolder对象,并把指针赋给Binder.mObject。gBinderOffsets和前面的gBinderProxyOffsets类似,也是在程序启动时初始化的,他的结构体代码如下
static struct bindernative_offsets_t
{
// Class state.
jclass mClass; //android.os.Binder
jmethodID mExecTransact; //android.os.Binder.execTransact();
// Object state.
jfieldID mObject; //android.os.Binder.mObject
} gBinderOffsets;
分析完Service的初始化之后,我们再看一下Service是怎样通过ServiceManagerProxy注册到service_manager里面的。
addService
ServiceManagerProxy的 addService代码如下
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);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
先把service写入到序列化类Parcel里面。然后调用mRemote.transact(),将序列化的数据发送出去。这里的mRemote就是我们前面初始化ServiceManagerProxy传入的BinderProxy。下面看一下Parcel.writeStrongBinder()
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}
nativeWriteStrongBinder是一个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);
}
}
}
parcel->writeStrongBinder()
在上一节已经分析过,如果是一个BpBinder它会将handle的值存入parcel中,如果是BBinder它会将BBinder 的this指针存储到 parcel中。这里我们是addService操作,所以我们可以大胆猜测括号里是一个BBinder的子类。下面我们看一下ibinderForJavaObject(env, object)是如何实现将Java的Servie和BBinder绑定的。
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//Binder.class
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {//BinderProxy.class
return (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
这里的obj是ActivityManagerService,它是Binder的子类。所以执行第二个if语句。还记得我们前面在讲Binder的构造函数时,在init里面我们在native层分配了一个JavaBBinderHolder类,并将它的指针存在mObject成员变量中。现在我们把它取出来然后调用他的get()函数。看一下这个类的源码实现。
class JavaBBinderHolder : public RefBase
{
public:
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;
}
sp<JavaBBinder> getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp<JavaBBinder> mBinder;
};
看一下get()函数,第一次调用时,mBinder为空,于是创建了一个JavaBBinder,并把obj传了进去。然后把JavaBBinder赋值给mBinder。接着看看JavaBBinder
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
bool checkSubclass(const void* subclassID) const
{
return subclassID == &gBinderOffsets;
}
jobject object() const
{
return mObject;
}
protected:
virtual ~JavaBBinder()
{
ALOGV("Destroying JavaBBinder %p\n", this);
android_atomic_dec(&gNumLocalRefs);
JNIEnv* env = javavm_to_jnienv(mVM);
env->DeleteGlobalRef(mObject);
}
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = )
{
...
}
virtual status_t dump(int fd, const Vector<String16>& args)
{
return ;
}
private:
JavaVM* const mVM;
jobject const mObject;
};
JavaBBinder会把传进来的service引用赋值给自己的mObject。可以看出Binder.class,JavaBBinderHolder,JavaBBinder这三者是一个循环持有的过程,他们的关系图为
这样Java层和c++层都持有了对方的引用。
同时JavaBBinder还是BBinder的子类。也就是说,ibinderForJavaObject返回了JavaBBinder也就是一个BBinder。下面我们看一下BinderProxy.transact()函数。
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
return transactNative(code, data, reply, flags);
}
transactNative()是一个jni实现,它的源码在android_os_Parcel.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 = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);//3
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
target, obj, code);
//printf("Transact from Java code to %p sending: ", target); data->print();
status_t err = target->transact(code, *data, reply, flags);//4
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
return JNI_FALSE;
}
在1,2里面分别把Java序列化的data和reply转变为一个c++的Parcle变量。3中取出了mObject值,在前面获得server_manager代理的时候我们把他初始化为一个BpBinder(0)。在4里面调用BpBinder->transact()函数。下面就进入了C++层和binder通信的过程,和上一篇博客分析的一样,会调用到IPCThreadState和binder驱动进行读写。到这里我们就已经把我们的ActivityManagerService注册到Binder驱动和 activity_manager里面 。
Binder驱动调用Service
上一节我们分析了Java中的Service如何注册到binder里面的。那么,binder又是如何调用到Service的业务实现的呢。在上一篇博客Binder通信笔记(native)篇中,我们看到在IPCProcessState读取到binder数据之后,会通过我们注册到binder驱动里面BBinder指针,调用它的transact()函数。在Java Serivce注册的时候,我们注册的是JavaBBinder,它是BBinder的子类。JavaBBinder并没有重写transact()函数,所以回复用BBinder中的实现,调用onTransact()函数。JavaBBinder重写了onTransact()的实现,我们看一下源码
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = )
{
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();
//printf("Transact from %p to Java code sending: ", this);
//data.print();
//printf("\n");
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
jthrowable excep = env->ExceptionOccurred();
if (excep) {
report_exception(env, excep,
"*** Uncaught remote exception! "
"(Exceptions are not yet supported across processes.)");
res = JNI_FALSE;
/* clean up JNI local ref -- we don't return to Java code */
env->DeleteLocalRef(excep);
}
// Check if the strict mode state changed while processing the
// call. The Binder state will be restored by the underlying
// Binder system in IPCThreadState, however we need to take care
// of the parallel Java state as well.
if (thread_state->getStrictModePolicy() != strict_policy_before) {
set_dalvik_blockguard_policy(env, strict_policy_before);
}
jthrowable excep2 = env->ExceptionOccurred();
if (excep2) {
report_exception(env, excep2,
"*** Uncaught exception in onBinderStrictModePolicyChange");
/* clean up JNI local ref -- we don't return to Java code */
env->DeleteLocalRef(excep2);
}
// Need to always call through the native implementation of
// SYSPROPS_TRANSACTION.
if (code == SYSPROPS_TRANSACTION) {
BBinder::onTransact(code, data, reply, flags);
}
//aout << "onTransact to Java code; result=" << res << endl
// << "Transact from " << this << " to Java code returning "
// << reply << ": " << *reply << endl;
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
第15行,调用了mObject的gBinderOffsets.mExecTransact函数,通过前面的分析知道,此处的mObject是一个Binder类的引用,gBinderOffsets.mExecTransact是Binder类的execTransact()方法。所以,业务处理分发给了Java层的Binder类的execTransact()。
// Entry point from android_util_Binder.cpp's onTransact
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
// Log any exceptions as warnings, don't silently suppress them.
// If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
try {
res = onTransact(code, data, reply, flags);
} catch (RemoteException e) {
if ((flags & FLAG_ONEWAY) != ) {
Log.w(TAG, "Binder call failed.", e);
} else {
reply.setDataPosition();
reply.writeException(e);
}
res = true;
} catch (RuntimeException e) {
if ((flags & FLAG_ONEWAY) != ) {
Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
} else {
reply.setDataPosition();
reply.writeException(e);
}
res = true;
} catch (OutOfMemoryError e) {
// Unconditionally log this, since this is generally unrecoverable.
Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e);
RuntimeException re = new RuntimeException("Out of memory", e);
reply.setDataPosition();
reply.writeException(re);
res = true;
}
checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
reply.recycle();
data.recycle();
// Just in case -- we are done with the IPC, so there should be no more strict
// mode violations that have gathered for this thread. Either they have been
// parceled and are now in transport off to the caller, or we are returning back
// to the main transaction loop to wait for another incoming transaction. Either
// way, strict mode begone!
StrictMode.clearGatheredViolations();
return res;
}
这里调用了onTransact(code, data, reply, flags),onTransact()在ActivityManagerService里面被继承了,真正的业务处理放在了这里 ,这样我们的Service函数就会被真正的执行,并且把执行后的结构存储在reply里面。
到这里我们就分析完了Java层和Binder驱动通信源码。
参考资料
http://blog.csdn.net/universus/article/details/6211589
http://blog.csdn.net/luoshengyang/article/details/6618363
http://blog.csdn.net/innost/article/details/47208049