您的位置:首页 > 移动开发 > Android开发

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

2016-12-03 11:19 866 查看
    文章仅仅用于个人的学习记录,基本上内容都是网上各个大神的杰作,此处摘录过来以自己的理解学习方式记录一下。

    个人最为认可和推崇的大神文章:

          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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息