我们在SystemServer分析这个文章中已经知道通过ServiceManager.addService("xx", new XXBinder(this));已经添加了很多服务,这些都是继承Binder的服务,需要跨进程操作。包括我们自己声明的服务也是一个道理,都是继承Binder。
并且我们上一章已经介绍了添加服务和查询服务的底层流程,但是问题来了,他们都是native层的,没有java的代码出现,那么Binder的通信是怎么和Java层建立联系的呢?
带着这个问题,我们就从Binder的构造方法追寻下去。
public Binder() { init(); ... }其中private native final void init(); 然后进入到android_utils_Binder.cpp中
这里的object是Java层继承Binder的服务类
我们在这里看到了gBinderOffsets.mExecTransact这个是java层方法名字,我们找到赋值的对应代码
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)); }也就是说在调用int_register_android_os_Binder的时候execTransact这个java层的方法的id会存到gBinderOffsets.mExecTransac变量中。
class JavaBBinder : public BBinder { public: JavaBBinder(JNIEnv* env, jobject object) : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)) { android_atomic_inc(&gNumLocalRefs); incRefsCreated(env); } bool checkSubclass(const void* subclassID) const { return subclassID == &gBinderOffsets; } jobject object() const { return mObject; } protected: virtual ~JavaBBinder() { 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 = 0) { JNIEnv* env = javavm_to_jnienv(mVM); IPCThreadState* thread_state = IPCThreadState::self(); const int32_t strict_policy_before = thread_state->getStrictModePolicy(); //这个代码调用的是execTransact方法将这些数据传递。 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags); if (code == SYSPROPS_TRANSACTION) { BBinder::onTransact(code, data, reply, flags); } return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; } virtual status_t dump(int fd, const Vector<String16>& args) { return 0; } private: JavaVM* const mVM; jobject const mObject;//对应的是Java层的Binder };到了这里,我们已经将Java层的Binder服务和Native层的BBinder联系起来。,从驱动层上来调用onTransact()方法就可以到达Java层的execTransact()方法。
在这里我们也注意一个问题,由于onTransact()方法是BBinder的函数,而现在JavaBBinder覆写了这个函数,所以调用的时候会调用到execTransact(),那么在那块才调用onTransact()呢?
BpBinder::transact()-> IPCThreadState::transact()-> IPCThreadState::waitForResponse()-> IPCThreadState::executeCommand()
此时的BBinder的派生类是JavaBBinder类,然后调用它的onTransact()这个方法会调用java层的execTransact()方法。
在使用IPCThreadState::transact发送数据的时候会调用waitForResponse()然后调用executeCommand()然后调用transact()然后调用onTransact()
也就是说在native层回复数据的时候会调用到onTransact()方法。
Binder.java中 下面我们看一看Java层的execTransact()
private boolean execTransact(int code, long dataObj, long replyObj, int flags) { Parcel data = Parcel.obtain(dataObj); Parcel reply = Parcel.obtain(replyObj); boolean res; try { res = onTransact(code, data, reply, flags);//回调继承java层Binder的onTransact()方法 } catch (RemoteException e) { if ((flags & FLAG_ONEWAY) != 0) { Log.w(TAG, "Binder call failed.", e); } else { reply.setDataPosition(0); reply.writeException(e); } res = true; } catch (RuntimeException e) { if ((flags & FLAG_ONEWAY) != 0) { } else { reply.setDataPosition(0); reply.writeException(e); } res = true; } catch (OutOfMemoryError e) { RuntimeException re = new RuntimeException("Out of memory", e); reply.setDataPosition(0); reply.writeException(re); res = true; } checkParcel(this, code, reply, "Unreasonably large binder reply buffer"); reply.recycle(); data.recycle(); StrictMode.clearGatheredViolations(); return res; }我们下面将会看到对应java层Binder的方法
应用在Java层的Binder引用是通过Binder的代理完成的。
我们首先看一个aidl产生的文件,然后进行分析:
public interface IHelloService extends android.os.IInterface { public static abstract class Stub extends android.os.Binder implements IHelloService { private static final java.lang.String DESCRIPTOR = "IHelloService"; public Stub() { this.attachInterface(this, DESCRIPTOR); } public static IHelloService asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof IHelloService))) { return ((IHelloService)iin); } return new IHelloService.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_sayhello: { data.enforceInterface(DESCRIPTOR); this.sayhello(); reply.writeNoException(); return true; } case TRANSACTION_sayhello_to: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); int _result = this.sayhello_to(_arg0); reply.writeNoException(); reply.writeInt(_result); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements IHelloService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public void sayhello() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public int sayhello_to(java.lang.String name) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(name); mRemote.transact(Stub.TRANSACTION_sayhello_to, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_sayhello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_sayhello_to = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public void sayhello() throws android.os.RemoteException; public int sayhello_to(java.lang.String name) throws android.os.RemoteException; }下面是调用方法:
/* 1. getService */ IBinder binder = ServiceManager.getService("hello"); if (binder == null) { System.out.println("can not get hello service"); Slog.i(TAG, "can not get hello service"); return; } IHelloService svr = IHelloService.Stub.asInterface(binder);我们通过aidl产生的java文件可以看出来通过asInterface方法
public static IHelloService asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof IHelloService))) { return ((IHelloService)iin); } return new IHelloService.Stub.Proxy(obj); } private static class Proxy implements IHelloService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } ... }当调用的时候svr.sayhello();
就会调用:
@Override public void sayhello() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } }我们都知道mRemote其实就是BpBinder对象。
所以调用BpBinder对象的transact方法
status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) { status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT; }这个方法我们之前已经分析过了,是通过BpBinder的写数据,读数据
我们先从Binder的构造出发,因为Binder服务可以是SystemServer添加的服务,也可以是自己创建的匿名服务,但是都会调用构造方法。发现构造方法中调用native层的init方法,init()方法做的事情就是创建JavaBBinderHolder对象这个对象中get方法会得到JavaBBinder对象,JavaBBinder对象继承BBinder类。并且重写BBinder的onTransact()方法,onTransact()会调用java层的execTransact(),这样就可以将Java层和native层的连接起来。
然后我们分析了从驱动如何调用到BBinder的onTransact()方法,我们的调用顺序是: BpBinder::transact()-> IPCThreadState::transact()-> IPCThreadState::waitForResponse()-> IPCThreadState::executeCommand() 我们上篇文章分析了BpBinder是BpServiceManager成员变量mRemote也就是native层通过sp<IServiceManager> sm(defaultServiceManager());方法得到的.
其中BpBinder可以调用到BpBinder::transact()->IPCThreadState::self()->transact()和驱动进行通信.这个方法会调用到IPCThreadState::executeCommand()这个方法会调用
sp<BBinder> b((BBinder*)tr.cookie); error = b->transact(tr.code, buffer, &reply, tr.flags);其中b->transact()会调用onTransact()这里注意b是BBinder我们在java代码中看到是JavaBBinder继承与BBinder,所以此时会调用JavaBBinder的onTransact(),在这个回调函数中我们将可以看到调用execTransact(),然后我们在Binder.java的execTransact()方法中看到又调用Binder.java的onTransact()方法,所以回调了我们生成的aidl文件中的onTransact()方法。
最后我们也从java层出发看了是如何通信到底层的,我们在aidl产生的文件中可以看到
sayhello(): mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0);其中mRemote就是BpBinder。
这样我们就从java到底层完成了整个流程的创建。