Android Binder源码阅读

25 篇文章 0 订阅
9 篇文章 0 订阅

作为Android 主要的IPC方式Binder, 其实现了IBinder接口,通过代理模式,parcelable序列化反序列操作,实现了RPC,即跨进程调用

1.IBinder接口

首先Binder 实现了IBinder接口,故先来看看IBinder接口,IBinder代码只有四十行功能比较清晰。

public interface IBinder {
    //IBinder协议传输码, 用来获得网络状态
    int DUMP_TRANSACTION = 1598311760;
    //第一次传输回调传输码
    int FIRST_CALL_TRANSACTION = 1;
    //IBinder协议传输码,用于 transact(int, Parcel, Parcel, int),oneway意味着caller返回很快,不会等待结果
    int FLAG_ONEWAY = 1;
    //Binder协议传输码,用于查询事务的接收方以获得其规范接口描述符。
    int INTERFACE_TRANSACTION = 1598968902;
    //上一次传输回调传输码
    int LAST_CALL_TRANSACTION = 16777215;
    //IBinder协议传输码,异步调用app
    int LIKE_TRANSACTION = 1598835019;
    //IBinder协议传输码,pingBinder()的传输码
    int PING_TRANSACTION = 1599098439;
    //IBinder协议传输码,向对象发送一个tweet
    int TWEET_TRANSACTION = 1599362900;

    @Nullable
    //获取接口描述
    String getInterfaceDescriptor() throws RemoteException;
	//检查对象是否存在
    boolean pingBinder();
	//检查进程的Binder是否活着
    boolean isBinderAlive();
	//尝试检索一个Binder的本地接口
    @Nullable
    IInterface queryLocalInterface(@NonNull String var1);
	//获得对象的状态
    void dump(@NonNull FileDescriptor var1, @Nullable String[] var2) throws RemoteException;
	//异步的获得对象的状态
    void dumpAsync(@NonNull FileDescriptor var1, @Nullable String[] var2) throws RemoteException;
	//对对象执行泛型操作
    boolean transact(int var1, @NonNull Parcel var2, @Nullable Parcel var3, int var4) throws RemoteException;
	//注册Binder死亡监听
    void linkToDeath(@NonNull IBinder.DeathRecipient var1, int var2) throws RemoteException;
	//移除Binder死亡监听
    boolean unlinkToDeath(@NonNull IBinder.DeathRecipient var1, int var2);
	//Binder死亡监听回调接口
    public interface DeathRecipient {
        void binderDied();
    }
}


2.Binder源码分析

2.1 内部类 NoImagePreloadHolder

//使用Holder允许在引导映像中静态初始化绑定器,是为了避免一些初始化排序可能的问题。

   private static class NoImagePreloadHolder {
       public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
                Binder.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
  }

2.2Binder内部变量

FIND_POTENTIAL_LEAKS 用于设置FLAG是否检查可能的内存泄露
CHECK_PARCEL_SIZE 用于设置FLAG是否检查Parcel 大小
LOG_RUNTIME_EXCEPTION 用于设置FLAG是否检查运行异常
sDumpDisabled 控制dump是否可被调用
sTransactionTracker 全局进程transaction tracker

2.3 主要的业务函数

pintBinder 默认返回true

isBinderAlive 默认返回true

onTransact
transact()的回调函数,对传输对象进行序列化操作

    protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
            int flags) throws RemoteException {
            //data对象是序列化Parcel类携带数据,reply对象是序列化类返回给调用者的结果
            //往返回值中写入接口描述字段
        if (code == INTERFACE_TRANSACTION) {
            reply.writeString(getInterfaceDescriptor());
            return true;
        } else if (code == DUMP_TRANSACTION) {
            ParcelFileDescriptor fd = data.readFileDescriptor();
            String[] args = data.readStringArray();
            if (fd != null) {
                try {
                    dump(fd.getFileDescriptor(), args);
                } finally {
                    IoUtils.closeQuietly(fd);
                }
            }
            // Write the StrictMode header.
            if (reply != null) {
                reply.writeNoException();
            } else {
                StrictMode.clearGatheredViolations();
            }
            return true;
        } else if (code == SHELL_COMMAND_TRANSACTION) {
            ParcelFileDescriptor in = data.readFileDescriptor();
            ParcelFileDescriptor out = data.readFileDescriptor();
            ParcelFileDescriptor err = data.readFileDescriptor();
            String[] args = data.readStringArray();
            ShellCallback shellCallback = ShellCallback.CREATOR.createFromParcel(data);
            ResultReceiver resultReceiver = ResultReceiver.CREATOR.createFromParcel(data);
            try {
                if (out != null) {
                    shellCommand(in != null ? in.getFileDescriptor() : null,
                            out.getFileDescriptor(),
                            err != null ? err.getFileDescriptor() : out.getFileDescriptor(),
                            args, shellCallback, resultReceiver);
                }
            } finally {
                IoUtils.closeQuietly(in);
                IoUtils.closeQuietly(out);
                IoUtils.closeQuietly(err);
                // Write the StrictMode header.
                if (reply != null) {
                    reply.writeNoException();
                } else {
                    StrictMode.clearGatheredViolations();
                }
            }
            return true;
        }
        return false;
    }

transact() 默认的实现传递parcel对象并调用onTransact。在客户端,transact会调用Binder 代理类实现IPC,跨进程调用

    public final boolean transact(int code, @NonNull Parcel data, @Nullable 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;
    }

客户端中的BinderProxy的transact() 中调用native函数 transactNative进行传值

    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");

        if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
            // For now, avoid spamming the log by disabling after we've logged
            // about this interface at least once
            mWarnOnBlocking = false;
            Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
                    new Throwable());
        }

        final boolean tracingEnabled = Binder.isTracingEnabled();
        if (tracingEnabled) {
            final Throwable tr = new Throwable();
            Binder.getTransactionTracker().addTrace(tr);
            StackTraceElement stackTraceElement = tr.getStackTrace()[1];
            Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
                    stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
        }
        try {
            return transactNative(code, data, reply, flags);
        } finally {
            if (tracingEnabled) {
                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值