android Binder那点事儿
来源:互联网 发布:启发式算法的应用案例 编辑:程序博客网 时间:2024/05/29 15:07
年后第一篇,在这里首先祝大家新年快乐。
之前我们总是提到“这是binder的事情,这里暂不做解释”,现在我们就解释解释binder的事儿。还从我们之前的某个地方开始,这个地方叫ActivityManagerNative,当然了,只要我们把这儿梳理通了,那其它有关binder的事情我们基本都能理解了。首先我们先给出一个流程图
通过这个图我们大致可以明白binder的基本调用流程,我们一步一步看下去,首先在ActivityManagerNative.java中有个类叫做ActivityManagerProxy,还是从我们之前提到的startActivity看起,在startActivity中有这么一句话mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);之前我们把这句话跳过去了,现在我们分析一下,首先我们分析一下mRemote是什么,很明显,mRemote是IBinder的实例,但在这里mRemote又代表了什么呢?我们深挖一下。mRemote是在ActivityManagerProxy构造函数中被初始化的,代码如下
public ActivityManagerProxy(IBinder remote) { mRemote = remote; }
显而易见,mRemote是ActivityManagerProxy被实例化的时候传进来的参数赋值而成的,而ActivityManagerProxy类是在哪里被实例化的呢?很容易发现,是在ActivityManagerNative这个类
中
static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ActivityManagerProxy(obj); }
显而易见,ActivityManagerProxy被new的时候传进去的参数是asInterface被调用的时候传进来的参数,也就是这里的obj,而asInterface是在初始化gDefault的时候被调用的
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };
也就是IActivityManager am = asInterface(b);而我们这里的b是什么呢?也就是IBinder b = ServiceManager.getService("activity");了。至此我们知道了其实我们的mRemote就是
ServiceManager.getService("activity")了。知道这些够嘛?很显然不够,我们还需要深挖。说到这里我们需要提醒一下,上面的分析过程,是不是看起来很熟悉啊,对了,这个过程我们之
前正着分析过一次,现在是反着分析了一下,如果不清楚的童鞋可以看看我之前的分析文章。别的不多说,我们接着深挖,看看ServiceManager.getService("activity")背后的故事。
我们进ServiceManager中看一下getService的内容
public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return getIServiceManager().getService(name); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; }
很明显我们最终返回的是getIServiceManager().getService(name);至于sCache.get(name);个东西,其实都是从getIServiceManager().getService(name);完成缓存的,不再分析。下面我们
分析getIServiceManager().getService(name);句话,首先我们就看getIServiceManager()了
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
很明显我们返回的是IServiceManager,也就是ServiceManagerNative.asInterface(BinderInternal.getContextObject());进到ServiceManagerNative.asInterface中我们就会发现我们这里
返回的IServiceManager对象其实就是IServiceManager的子类ServiceManagerProxy,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); }
而ServiceManagerProxy里面的IBinder对象mRemote就是我们传进来的BinderInternal.getContextObject(),所以getIServiceManager().getService(name)也就成了
ServiceManagerProxy.getService(name)也就是
public IBinder getService(String name) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; }
而这里的mRemote也就是我们传来的BinderInternal.getContextObject()这个刚才我们说过了。接下来我们就分析BinderInternal.getContextObject(),在BinderInternal中我们会发现
getContextObject()是一个native类,我们都知道这类类的实现都是C或C++了,也就是我们说的JNI了,所以我们可以找到这个C++类叫做android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = { /* name, signature, funcPtr */ { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject }, { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool }, { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling }, { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }};
所以getContextObject也就对应这C++中的android_os_BinderInternal_getContextObject了,我们去android_os_BinderInternal_getContextObject中看看
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz){ sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b);}
在这里我们有发现了IBinder,很惊喜吧,首先我们先看看ProcessState::self()->getContextObject(NULL);是什么,进入ProcessState中找到getContextObject也就是
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){ return getStrongProxyForHandle(0);}
getStrongProxyForHandle又是什么
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){ sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { // We need to create a new BpBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { b = new BpBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { // This little bit of nastyness is to allow us to add a primary // reference to the remote proxy when this team doesn't have one // but another team is sending the handle to us. result.force_set(b); e->refs->decWeak(this); } } return result;}
在这里我们就会发现,其实我们得到是BpBinder,所以ProcessState::self()->getContextObject(NULL);其实就是BpBinder(0);这里的参数为什么是0呢?0指的就是我们ServiceManager的
binder对象,这个是唯一的,所以javaObjectForIBinder(env, b);也就是javaObjectForIBinder(env,BpBinder(0)),接着我们就说说javaObjectForIBinder了
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 of Java proxies for native Binder proxies. AutoMutex _l(mProxyLock); // Someone else's... do we know about it? jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet); if (res != NULL) { LOGV("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); } 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->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); 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)); 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->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get())); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object;}
这里我么就说一下env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());了,很明显我们把传进来的BpBinder用gBinderProxyOffsets.mObject来标识了,也就说通过
gBinderProxyOffsets.mObject我们可以找到这个BpBinder了,其它的代码我们不做过多分析,很明显我们这里返回了一个包含gBinderProxyOffsets信息object,而gBinderProxyOffsets又是
什么呢?在int_register_android_os_BinderProxy中我们可以找到答案
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"); LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference"); gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gWeakReferenceOffsets.mGet = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;"); assert(gWeakReferenceOffsets.mGet); clazz = env->FindClass("java/lang/Error"); LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error"); gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); clazz = env->FindClass(kBinderProxyPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy"); gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderProxyOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); assert(gBinderProxyOffsets.mConstructor); gBinderProxyOffsets.mSendDeathNotice = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V"); assert(gBinderProxyOffsets.mSendDeathNotice); gBinderProxyOffsets.mObject = env->GetFieldID(clazz, "mObject", "I"); assert(gBinderProxyOffsets.mObject); gBinderProxyOffsets.mSelf = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;"); assert(gBinderProxyOffsets.mSelf); gBinderProxyOffsets.mOrgue = env->GetFieldID(clazz, "mOrgue", "I"); assert(gBinderProxyOffsets.mOrgue); clazz = env->FindClass("java/lang/Class"); LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class"); gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;"); assert(gClassOffsets.mGetName); return AndroidRuntime::registerNativeMethods( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods));}
从这里我们可以看出gBinderProxyOffsets其实就是android/os/BinderProxy我们的java类,也就是我们上面返回的是一个BinderProxy,BinderProxy是什么呢,一会我们会讲到,也就是说
BinderInternal.getContextObject()我们最终得到是BinderProxy,也就是我们ServiceManager中的ServiceManagerNative.asInterface(BinderInternal.getContextObject());其实就是
ServiceManagerNative.asInterface(BinderProxy);也就是getIServiceManager().getService(name);其实就是ServiceManagerNative.asInterface(BinderProxy).getService(name)。所以
我么就又回到ServiceManagerProxy类中的getService了,也就是
public IBinder getService(String name) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; }
上面我们分析到这里的时候停下了,所以我们接着这里分析,上面我们分析过mRemote就是我们ServiceManagerNative.asInterface传进来的参数也就是BinderProxy的一个对象,而此时的
BinderProxy对象也就是我们ServiceManager的binder对象。这是我们的ServiceManagerProxy的mRemote由来,mRemote最终就是一个BinderProxy对象。
接下来我们接着说ActivityManagerProxy中的mRemote是什么,它也就是IBinder binder = reply.readStrongBinder();这个东西,之前我们已经分析到这里了,reply是Parcel的实例,我们
进Parcel去看看readStrongBinder也就是
public final native IBinder readStrongBinder();
又是一个native函数,这个函数同样再JNI层的android_util_Binder.cpp中实现
static const JNINativeMethod gParcelMethods[] = { {"dataSize", "()I", (void*)android_os_Parcel_dataSize}, {"dataAvail", "()I", (void*)android_os_Parcel_dataAvail}, {"dataPosition", "()I", (void*)android_os_Parcel_dataPosition}, {"dataCapacity", "()I", (void*)android_os_Parcel_dataCapacity}, {"setDataSize", "(I)V", (void*)android_os_Parcel_setDataSize}, {"setDataPosition", "(I)V", (void*)android_os_Parcel_setDataPosition}, {"setDataCapacity", "(I)V", (void*)android_os_Parcel_setDataCapacity}, {"pushAllowFds", "(Z)Z", (void*)android_os_Parcel_pushAllowFds}, {"restoreAllowFds", "(Z)V", (void*)android_os_Parcel_restoreAllowFds}, {"writeNative", "([BII)V", (void*)android_os_Parcel_writeNative}, {"writeInt", "(I)V", (void*)android_os_Parcel_writeInt}, {"writeLong", "(J)V", (void*)android_os_Parcel_writeLong}, {"writeFloat", "(F)V", (void*)android_os_Parcel_writeFloat}, {"writeDouble", "(D)V", (void*)android_os_Parcel_writeDouble}, {"writeString", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString}, {"writeStrongBinder", "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor}, {"createByteArray", "()[B", (void*)android_os_Parcel_createByteArray}, {"readInt", "()I", (void*)android_os_Parcel_readInt}, {"readLong", "()J", (void*)android_os_Parcel_readLong}, {"readFloat", "()F", (void*)android_os_Parcel_readFloat}, {"readDouble", "()D", (void*)android_os_Parcel_readDouble}, {"readString", "()Ljava/lang/String;", (void*)android_os_Parcel_readString}, {"readStrongBinder", "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, {"internalReadFileDescriptor", "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor}, {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor}, {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor}, {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor}, {"freeBuffer", "()V", (void*)android_os_Parcel_freeBuffer}, {"init", "(I)V", (void*)android_os_Parcel_init}, {"destroy", "()V", (void*)android_os_Parcel_destroy}, {"marshall", "()[B", (void*)android_os_Parcel_marshall}, {"unmarshall", "([BII)V", (void*)android_os_Parcel_unmarshall}, {"appendFrom", "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom}, {"hasFileDescriptors", "()Z", (void*)android_os_Parcel_hasFileDescriptors}, {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken}, {"enforceInterface", "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},};
很明显readStrongBinder也就是C++中的android_os_Parcel_readStrongBinder我们去看看
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz){ Parcel* parcel = parcelForJavaObject(env, clazz); if (parcel != NULL) { return javaObjectForIBinder(env, parcel->readStrongBinder()); } return NULL;}
javaObjectForIBinder这个我们之前已经分析过了,不再赘述,它返回是一个java层的BinderProxy对象,所以ActivityManagerProxy中的mRemote同样也是一个BinderProxy对象,至此我们终
于找到了mRemote的真是面目也就是BinderProxy对象,所以回到最开始的mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);也就是BinderProxy.transact
(START_ACTIVITY_TRANSACTION, data, reply, 0)了。那我们就去看看BinderProxy中的transact吧,BinderProxy是在Binder.java文件中,BinderProxy继承于IBinder,BinderProxy中的
transact也就是
public native boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException;
还是一个native方法,同样我们去JNI层查看,仍在文件android_util_Binder.cpp中
static const JNINativeMethod gBinderProxyMethods[] = { /* name, signature, funcPtr */ {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder}, {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive}, {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor}, {"transact", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact}, {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}, {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath}, {"destroy", "()V", (void*)android_os_BinderProxy_destroy},};
所以BinderProxy中的transact也就是C++中的android_os_BinderProxy_transact方法
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); if (data == NULL) { return JNI_FALSE; } Parcel* reply = parcelForJavaObject(env, replyObj); if (reply == NULL && replyObj != NULL) { return JNI_FALSE; } IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; } LOGV("Java code calling transact on %p in Java object %p with code %d\n", target, obj, code); // Only log the binder call duration for things on the Java-level main thread. // But if we don't const bool time_binder_calls = should_time_binder_calls(); int64_t start_millis; if (time_binder_calls) { start_millis = uptimeMillis(); } //printf("Transact from Java code to %p sending: ", target); data->print(); status_t err = target->transact(code, *data, reply, flags); //if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); if (time_binder_calls) { conditionally_log_binder_call(start_millis, target, code); } if (err == NO_ERROR) { return JNI_TRUE; } else if (err == UNKNOWN_TRANSACTION) { return JNI_FALSE; } signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); return JNI_FALSE;}
首先看
IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject);
我们之前提到过gBinderProxyOffsets.mObject可以找到我们创建的BpBinder对象,所以这里的target其实就是指向BpBinder的
status_t err = target->transact(code, *data, reply, flags);
也就成了BpBinder->transact(code, *data, reply, flags);我们去BpBinder中观看
status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ // Once a binder has died, it will never come back to life. if (mAlive) { status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT;}
也就是
status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags);
了,那我们就去看IPCThreadState中的transact了
status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ status_t err = data.errorCheck(); flags |= TF_ACCEPT_FDS; IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand " << handle << " / code " << TypeCode(code) << ": " << indent << data << dedent << endl; } if (err == NO_ERROR) { LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(), (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY"); err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); } if (err != NO_ERROR) { if (reply) reply->setError(err); return (mLastError = err); } if ((flags & TF_ONE_WAY) == 0) { #if 0 if (code == 4) { // relayout LOGI(">>>>>> CALLING transaction 4"); } else { LOGI(">>>>>> CALLING transaction %d", code); } #endif if (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } #if 0 if (code == 4) { // relayout LOGI("<<<<<< RETURNING transaction 4"); } else { LOGI("<<<<<< RETURNING transaction %d", code); } #endif IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand " << handle << ": "; if (reply) alog << indent << *reply << dedent << endl; else alog << "(none requested)" << endl; } } else { err = waitForResponse(NULL, NULL); } return err;}
很简单最终是走到waitForResponse这个方法中去的
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){ int32_t cmd; int32_t err; while (1) { if ((err=talkWithDriver()) < NO_ERROR) break; err = mIn.errorCheck(); if (err < NO_ERROR) break; if (mIn.dataAvail() == 0) continue; cmd = mIn.readInt32(); IF_LOG_COMMANDS() { alog << "Processing waitForResponse Command: " << getReturnString(cmd) << endl; } switch (cmd) { case BR_TRANSACTION_COMPLETE: if (!reply && !acquireResult) goto finish; break; case BR_DEAD_REPLY: err = DEAD_OBJECT; goto finish; case BR_FAILED_REPLY: err = FAILED_TRANSACTION; goto finish; case BR_ACQUIRE_RESULT: { LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT"); const int32_t result = mIn.readInt32(); if (!acquireResult) continue; *acquireResult = result ? NO_ERROR : INVALID_OPERATION; } goto finish; case BR_REPLY: { binder_transaction_data tr; err = mIn.read(&tr, sizeof(tr)); LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY"); if (err != NO_ERROR) goto finish; if (reply) { if ((tr.flags & TF_STATUS_CODE) == 0) { reply->ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); } else { err = *static_cast<const status_t*>(tr.data.ptr.buffer); freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); } } else { freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); continue; } } goto finish; default: err = executeCommand(cmd); if (err != NO_ERROR) goto finish; break; } }finish: if (err != NO_ERROR) { if (acquireResult) *acquireResult = err; if (reply) reply->setError(err); mLastError = err; } return err;}
很明显是个死循环了,我们只挑我们关心的讲,在循环中首先执行talkWithDriver(),从名字可以看出是在和驱动通话,交换数据信息,暂时不再赘述,以后有机会再进行讲解,如果数据交
换成功就会继续执行,如果不成功就继续等待了,如果成功了就会去判断我们执行的是什么命令,而我们这里执行的是BR_TRANSACTION,也就会进入default语句的executeCommand中,也就是
case BR_TRANSACTION: { binder_transaction_data tr; result = mIn.read(&tr, sizeof(tr)); LOG_ASSERT(result == NO_ERROR, "Not enough command data for brTRANSACTION"); if (result != NO_ERROR) break; Parcel buffer; buffer.ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); const pid_t origPid = mCallingPid; const uid_t origUid = mCallingUid; mCallingPid = tr.sender_pid; mCallingUid = tr.sender_euid; int curPrio = getpriority(PRIO_PROCESS, mMyThreadId); if (gDisableBackgroundScheduling) { if (curPrio > ANDROID_PRIORITY_NORMAL) { // We have inherited a reduced priority from the caller, but do not // want to run in that state in this process. The driver set our // priority already (though not our scheduling class), so bounce // it back to the default before invoking the transaction. setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL); } } else { if (curPrio >= ANDROID_PRIORITY_BACKGROUND) { // We want to use the inherited priority from the caller. // Ensure this thread is in the background scheduling class, // since the driver won't modify scheduling classes for us. // The scheduling group is reset to default by the caller // once this method returns after the transaction is complete. androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_BG_NONINTERACT); } } //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid); Parcel reply; IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BR_TRANSACTION thr " << (void*)pthread_self() << " / obj " << tr.target.ptr << " / code " << TypeCode(tr.code) << ": " << indent << buffer << dedent << endl << "Data addr = " << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer) << ", offsets addr=" << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl; } if (tr.target.ptr) { sp<BBinder> b((BBinder*)tr.cookie); const status_t error = b->transact(tr.code, buffer, &reply, tr.flags); if (error < NO_ERROR) reply.setError(error); } else { const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); if (error < NO_ERROR) reply.setError(error); } //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n", // mCallingPid, origPid, origUid); if ((tr.flags & TF_ONE_WAY) == 0) { LOG_ONEWAY("Sending reply to %d!", mCallingPid); sendReply(reply, 0); } else { LOG_ONEWAY("NOT sending reply to %d!", mCallingPid); } mCallingPid = origPid; mCallingUid = origUid; IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj " << tr.target.ptr << ": " << indent << reply << dedent << endl; } } break;
executeCommand中的代码过多,这里我们只截取我们需要的,在这里会走到
if (tr.target.ptr) { sp<BBinder> b((BBinder*)tr.cookie); const status_t error = b->transact(tr.code, buffer, &reply, tr.flags); if (error < NO_ERROR) reply.setError(error); } else { const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); if (error < NO_ERROR) reply.setError(error); }
在这里我们认识了一个新的IBinder叫BBinder,它继承于IBinder。the_context_object是sp<BBinder>,同样也是BBinder,而我们这里的BBinder其实它的子类JavaBBinder,而JavaBBinder
包含了我们Java的某个对象,首先我们进BBinder中看看transact方法
status_t BBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ data.setDataPosition(0); status_t err = NO_ERROR; switch (code) { case PING_TRANSACTION: reply->writeInt32(pingBinder()); break; default: err = onTransact(code, data, reply, flags); break; } if (reply != NULL) { reply->setDataPosition(0); } return err;}
也就是onTransact(code, data, reply, flags);方法,由于JavaBBinder中重写了次方法,所以就会走到JavaBBinder中的onTransact方法,JavaBBinder是android_util_Binder.cpp中的类,
所以我们进去看看
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) { JNIEnv* env = javavm_to_jnienv(mVM); LOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM); IPCThreadState* thread_state = IPCThreadState::self(); const int strict_policy_before = thread_state->getStrictModePolicy(); thread_state->setLastTransactionBinderFlags(flags); //printf("Transact from %p to Java code sending: ", this); //data.print(); //printf("\n"); jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, (int32_t)&data, (int32_t)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); } // Restore the Java binder thread's state if it changed while // processing a call (as it would if the Parcel's header had a // new policy mask and Parcel.enforceInterface() changed // it...) const int strict_policy_after = thread_state->getStrictModePolicy(); if (strict_policy_after != strict_policy_before) { // Our thread-local... thread_state->setStrictModePolicy(strict_policy_before); // And the Java-level thread-local... 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); } //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; }
我们只看这里的
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, (int32_t)&data, (int32_t)reply, flags);
很明显了,用gBinderOffsets.mExecTransact来执行了,而gBinderOffsets.mExecTransact是什么呢?
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); gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z"); assert(gBinderOffsets.mExecTransact); gBinderOffsets.mObject = env->GetFieldID(clazz, "mObject", "I"); assert(gBinderOffsets.mObject); return AndroidRuntime::registerNativeMethods( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods));}
很明显了是我们java层的android/os/Binder类中的execTransact方法,这样我们又回到java层了,去看看
private boolean execTransact(int code, int dataObj, int 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; try { res = onTransact(code, data, reply, flags); } catch (RemoteException e) { reply.writeException(e); res = true; } catch (RuntimeException e) { reply.writeException(e); res = true; } catch (OutOfMemoryError e) { RuntimeException re = new RuntimeException("Out of memory", e); reply.writeException(re); res = true; } reply.recycle(); data.recycle(); return res; }
很明显了调用了onTransact也就是,由于ActivityManagerNative的继承于Binder并重写了onTransact方法,所以就会走到ActivityManagerNative中的onTransact也就是
case START_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR); int grantedMode = data.readInt(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() == 1; String profileFile = data.readString(); ParcelFileDescriptor profileFd = data.readInt() != 0 ? data.readFileDescriptor() : null; boolean autoStopProfiler = data.readInt() != 0; int result = startActivity(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler); reply.writeNoException(); reply.writeInt(result); return true; }
了,之后的事情我们之前的文章已经讲过了,这里不在重复了。
由于binder的事情过多,某些地方跳过,以后有机会补上,还是那句话,给大师取乐,给后来者抛砖引玉,别在背后骂我就谢天谢地了。
- android Binder那点事儿
- Android那点事儿
- android Launcher那点事儿
- android activity那点事儿
- android 摇一摇那点事儿
- android Surface 那点事儿
- android PackageInstaller那点事儿
- android PackageInstaller那点事儿
- Android内存那点事儿
- android权限那点事儿
- android那点事儿 开篇寄语
- android 锁屏那点事儿
- android 悬浮窗那点事儿
- android Launcher那点事儿(二)
- 关于Android WebView的那点事儿..
- Android 封装Json数据那点事儿
- 关于android传感器的那点事儿
- 聊聊 Android ANR 那点事儿
- JavaScript数组对象常用操作汇总
- 移动UIView的方法
- 深入分析Cocos2d-x 2.0中的“纹理”和精灵-沈大海cocos2d-x教程20
- hbase常去学习网站
- 经典java题(英文版)
- android Binder那点事儿
- 《研磨struts2》第七章 值栈和OGNL 之 7.1 值栈
- Spring框架参考文档-目录
- python 字符串转时间
- cmd 修改默认字符集
- 第十三章:遍历n个元素取出等概率随机取出其中之一元素
- 以WebLogic 11g + MyEclipse 6.5 + EditPlus 3为例部署ArcGIS API for JavaScript 3.1离线包
- 设备管理
- 绑定变量导致执行计划不走索引