Android5.0中Binder机制相关的native层和java层中的Binder代理和实体的对象的分析

    xiaoxiao2021-12-14  16

    文章仅仅用于个人的学习记录,基本上内容都是网上各个大神的杰作,此处摘录过来以自己的理解学习方式记录一下。     个人最为认可和推崇的大神文章:            http://blog.csdn.net/luoshengyang/article/details/6618363     罗升阳Binder系列文章            http://blog.csdn.net/innost/article/details/47208049                Innost的Binder讲解

              https://my.oschina.net/youranhongcha/blog/149575              侯 亮的Binder系列文章.

    1、java层的binder相关方法总结.

       1.1、Binder       1)、获取正在进行跨进程调用的进程的uid、pid以及一些清楚和恢复的方法. public static final native int getCallingPid(); public static final native int getCallingUid(); public static final native long clearCallingIdentity(); public static final native void restoreCallingIdentity(long token);       2)、queryLocalInterface(String descriptor)           当前不是出于跨进程调用时候会返回mOwner,否则返回null。配合attachInterface          private String mDescriptor; public IInterface queryLocalInterface(String descriptor) { if (mDescriptor.equals(descriptor)) { return mOwner; } return null; } public void attachInterface(IInterface owner, String descriptor) { mOwner = owner; mDescriptor = descriptor; }       3)、getInterfaceDescriptor() public String getInterfaceDescriptor() { return mDescriptor; }        4 )、onTransact ()           一般来说都不会调用到此方法,会调用它的具体实现类,来完成各子的逻辑(在aidl生成的其实内部去去调用proxy了) protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { if (code == INTERFACE_TRANSACTION) { reply.writeString(getInterfaceDescriptor()); return true; } else if (code == DUMP_TRANSACTION) { //...... 处理一些通信异常信息 } return false; }        5 )、transact ()          内部主要的就是调用了onTransact()方法每次是叫如是子类对象在调用的话,那么很显然调用到了子类重写的onTransact当中. public final boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { if (false) Log.v("Binder", "Transact: " + code + " to " + this); if (data != null) { data.setDataPosition(0); } boolean r = onTransact(code, data, reply, flags); if (reply != null) { reply.setDataPosition(0); } return r; }        6 )、execTransact ()            这个函数很关键,是JNI层往java层走的切入点,在驱动处理完client端的请求的时候,服务端的处理函数就会回调到         这里。很显现就是去调用具体的Binder实现类的onTransact函数进而完成服务端的处理. // 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); boolean res; try { //此时相应的子类,有重写就调用自己的onTransact, res = onTransact(code, data, reply, flags); } catch (RemoteException e) { //...... } catch (RuntimeException e) { //...... } catch (OutOfMemoryError e) { //...... } //...... return res; }    2.1、BinderProxy          1 )、queryLocalInterface (String descriptor )              此时肯定是跨进程调用,这个方法返回null,从名字也可以看出来,毕竟它不是本地Local接口. public IInterface queryLocalInterface(String descriptor) {//代理端的这个查询本地接口返回的是null. return null; }          2 )、transact(...)              可以看出直接调用了native的方法transactNative,去进一步处理,请求驱动通信. public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException; 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); }          3 )、getInterfaceDescriptor ()             public native String getInterfaceDescriptor() throws RemoteException; 2、native层的重要的类的方法总结.    2.1、Binder对象的实体BBinder         1)、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);//就是调用自己的onTransact函数嘛,谁实例化的就调用谁! break; }   if (reply != NULL) { reply->setDataPosition(0); }   return err; }         2 )、onTransact (......).               这个方法一般也调用不到,会调用到子类重写的这个. status_t BBinder::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/) { switch (code) { case INTERFACE_TRANSACTION: reply->writeString16(getInterfaceDescriptor()); return NO_ERROR;   case DUMP_TRANSACTION: { int fd = data.readFileDescriptor(); int argc = data.readInt32(); Vector<String16> args; for (int i = 0; i < argc && data.dataAvail() > 0; i++) { args.add(data.readString16()); } return dump(fd, args); }   case SYSPROPS_TRANSACTION: { report_sysprop_change(); return NO_ERROR; }   default: return UNKNOWN_TRANSACTION; } }       3 )、queryLocalInterface (......).               此方法在IBinder类中默认实现是返回null,而BBinder和BpBinder都继承自它,所以没有额外的重写的时候也是返回nul.          但是在Binder机制中:class BnInterface : public INTERFACE, public BBinder 而每个实现的IXXX都要用这个更模板类,          在这个模板类中在IInterface.h文件中重写了 queryLocalInterface如下:                也是属于本进程的描述符的时候返回this.也就是BBinder对象. template<typename INTERFACE> inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface( const String16& _descriptor) { if (_descriptor == INTERFACE::descriptor) return this; return NULL; }     2.2、Binder的引用对象BpBinder.            1 )、构造 (int32_t handle ).                 这个参数很关键,用来查找相应的引用,并且通过IPCThreadState::self()来获得一个对象准备和驱动交互. BpBinder::BpBinder(int32_t handle) : mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(NULL) { ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);   extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle); }             2 )、transact (...... ).                 最主要的就是调用IPCThreadState对象的transact. 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) { //那mHandle就是咋实例化BpBinder的时候传入的. //BpBinder最终是调用IPCThreadState去和驱动打交道的,这个IPCThreadState每个线程一个. status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; }   return DEAD_OBJECT; }              3 )、 queryLocalInterface (......).                  由于BpBinder没有重写这个,它的子类BpInterface也没有重写,所以默认它是返回的null.

    转载请注明原文地址: https://ju.6miu.com/read-968627.html

    最新回复(0)