Binder 在 Android 中占有很重要的作用,这里就对 Binder 做个解析,也便于以后复习。
主要从以下几方面分析:

  1. Android 中的 IPC 机制
  2. AIDL 的使用及分析
  3. Binder 通信机制的分析

Android 中的 IPC 机制

Android 是基于 Linux 内核的,所以先看下 Linux 中的 IPC 机制

  • 管道
  • 信号
  • 消息队列
  • 信号灯
  • 共享内存
  • Socket
    这个就不详细看了,以后有时间了再研究

Android 的 IPC 机制

  • 通过文件共享
  • Socket
  • Messager
  • ContentProvider
  • AIDL

其中 Messager,ContentProvider,AIDL 都是基于 Binder,可以看出 Binder 的重要性,理解了 Binder 机制后感觉还是很巧妙的。

AIDL 的使用及分析

AIDL 的使用

  1. 创建 aidl 文件
  2. 在 aidl 文件中定义接口
package zy.com.uninstall.aidl;interface IMyAidlInterface {    void set(int val);    int get();}
  1. 构建工程生成 Java 文件
  2. 编写 Service 并集成 IMyAidlInterface.Stub() 重写接口函数,在 onBind() 中返回
public class MyServer extends Service {    @Nullable    @Override    public IBinder onBind(Intent intent) {        IMyAidlInterface binder = new IMyAidlInterface.Stub() {            @Override            public void set(int val) throws RemoteException {            }            @Override            public int get() throws RemoteException {                return 0;            }        };        return null;    }}
  1. 使用时在 onServiceConnected() 中获取到 IMyAidlInterface,之后就可以通过 binder 调用远程方法
    private void initService() throws RemoteException {        ServiceConnection connection = new ServiceConnection() {            @Override            public void onServiceConnected(ComponentName name, IBinder service) {                binder = IMyAidlInterface.Stub.asInterface(service);            }            @Override            public void onServiceDisconnected(ComponentName name) {            }        };        Intent intent = new Intent(this, MyServer.class);        bindService(intent, connection, BIND_AUTO_CREATE);    }

aidl 生成 java 文件的分析

创建 aidl 文件构建工程后,会自动生成下面的 java 文件

// IMyAidlInterface.javapackage zy.com.uninstall.aidl;// Declare any non-default types here with import statementspublic interface IMyAidlInterface extends android.os.IInterface {    /**     * Local-side IPC implementation stub class.     */    // service 方的 Binder    public static abstract class Stub extends android.os.Binder implements zy.com.uninstall.aidl.IMyAidlInterface {        private static final java.lang.String DESCRIPTOR = "zy.com.uninstall.aidl.IMyAidlInterface";        /**         * Construct the stub at attach it to the interface.         */        public Stub() {            this.attachInterface(this, DESCRIPTOR);        }        /**         * Cast an IBinder object into an zy.com.uninstall.aidl.IMyAidlInterface interface,         * generating a proxy if needed.         */        public static zy.com.uninstall.aidl.IMyAidlInterface asInterface(android.os.IBinder obj) {            if ((obj == null)) {                return null;            }            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);            // 如果 client 和 service 是同一个进程,直接返回 Stub 本身            if (((iin != null) && (iin instanceof zy.com.uninstall.aidl.IMyAidlInterface))) {                return ((zy.com.uninstall.aidl.IMyAidlInterface) iin);            }            // 如果 client 和 service 不是同一个进程,返回代理类            return new zy.com.uninstall.aidl.IMyAidlInterface.Stub.Proxy(obj);        }        @Override        public android.os.IBinder asBinder() {            return this;        }        // 通过 Binder 调用服务器进程,会执行这个函数,通过 code 来区分调用的函数        @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_set: { // 调用 set() 函数                    data.enforceInterface(DESCRIPTOR);                    int _arg0;                    _arg0 = data.readInt();                    this.set(_arg0); // 在 service 中实现                    reply.writeNoException();                    return true;                }                case TRANSACTION_get: { // 调用 get() 函数                    data.enforceInterface(DESCRIPTOR);                    int _result = this.get(); // 在 service 中实现                    reply.writeNoException();                    reply.writeInt(_result);                    return true;                }            }            return super.onTransact(code, data, reply, flags);        }        // Binder 的代理类,如果 client 和 service 不是同一个进程就会给 client 返回这个代理类        private static class Proxy implements zy.com.uninstall.aidl.IMyAidlInterface {            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 set(int val) throws android.os.RemoteException {                android.os.Parcel _data = android.os.Parcel.obtain();                android.os.Parcel _reply = android.os.Parcel.obtain();                try {                    // 对参数进行打包                    _data.writeInterfaceToken(DESCRIPTOR);                    _data.writeInt(val);                    // 调用服务器端的 transact() 函数,最终会调用到上面 Stub 中的 onTransact(),如果 service 端实现的方法耗时比较长,这个地方是会阻塞的                    mRemote.transact(Stub.TRANSACTION_set, _data, _reply, 0);                    _reply.readException();                } finally {                    _reply.recycle();                    _data.recycle();                }            }            @Override            public int get() 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);                    mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0);                    // 获取到返回参数                    _reply.readException();                    _result = _reply.readInt();                } finally {                    _reply.recycle();                    _data.recycle();                }                return _result;            }        }        // 对接口中方法的标志        static final int TRANSACTION_set = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);        static final int TRANSACTION_get = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);    }    public void set(int val) throws android.os.RemoteException;    public int get() throws android.os.RemoteException;}

上述代码在注释中对重要的地方做了解释,整体调用流程就是 service 中实现了 Stub 中的方法,并将 Binder 对象返回给 client,如果 client 和 service 在同一个进程,就返回 Stub 本身,否则返回 Proxy 对象,client 通过 Proxy 对象调用时,最终会调用到 Stub 的 onTransact() 函数,其中用 int 值来区分不同的函数。接下来详细分析下 Binder 的调用过程。

Binder 通信机制的分析

获取系统的 service

以后在写吧

ServiceManager 自身的注册和其他 service 的注册

这里放一张图说明整个过程

Binder详解_第1张图片binder_servicemanager.png

Binder 通信过程

这里放一张图说明整个过程

Binder详解_第2张图片binder_from_java_to_c_to_driver.png

关于 Binder 的资料

关于 Binder 的资料有很多,这里放一些个人感觉很好的连接,这些博客资料都比本文写的要好也更详细,但还要写这篇的原因是方便自己以后复习看,个人认为把流程绘制成图更好理解一些,以后有更详细的分析也会加进来。

资料如下:
Binder源码分析
深入理解Binder
Binder机制,从Java到C
红茶一杯话Binder

更多相关文章

  1. C语言函数以及函数的使用
  2. Android应用程序键盘(Keyboard)消息处理机制分析(1)
  3. Android:apk文件结构
  4. Android Layout文件的属性说明
  5. Android - Android 的消息机制
  6. Android开发艺术探索——第二章:IPC机制(上)
  7. Android学习笔记:Android消息处理机制之Handler介绍
  8. 在Android中建立Android project没有R.java文件

随机推荐

  1. 在Android中实现Hook机制的实验
  2. 从0开始学Android之Android生命周期
  3. 曝Android机冷冻后变"傻" 加密数据随意访
  4. Android应用开发笔记(13): Android移动应
  5. 2016年10月Android岗校招笔试面试总结
  6. findlibrary returned null产生的联想,And
  7. 使用Vitamio打造自己的Android万能播放器
  8. Android项目开发,不能不了解的第三方库!(齐
  9. Managing Your App's Memory 翻译
  10. Android Studio怎样提示函数使用方法