• 先创建不同需求的AIDL接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    interface ICompute {
    //计算加法的功能
    int add(int a,int b);
    }
    interface ISecurityCenter {
    //加密
    String encrypt(String content);
    //解密
    String decrypt(String password);
    }
  • 对创建的接口进行实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class ComputeImpl  extends  ICompute.Stub{
    @Override
    public int add(int a, int b) throws RemoteException {

    return a+b;
    }
    }
    public class SecurityCenterImpl extends ISecurityCenter.Stub{
    private static final char SECRET_CODE='^';
    @Override
    public String encrypt(String content) throws RemoteException {
    char[] chars = content.toCharArray();
    for (int i = 0; i < chars.length; i++) {
    // 核心加密逻辑
    chars[i] ^= SECRET_CODE;
    }
    return new String(chars);
    }

    @Override
    public String decrypt(String password) throws RemoteException {
    return encrypt(password);
    }
    }
  • 为Binder连接池创建AIDL接口

    1
    2
    3
    4
    5
    6
    7
    8
    // IBinderPool.aidl
    package com.example.contentprovider;

    // Declare any non-default types here with import statements

    interface IBinderPool {
    IBinder queryBinder(int binderCode);
    }
  • Binder连接池的具体实现(首先要去绑定远程服务,绑定成功后,客户端可以通过queryBinder方法去获取各自对应的Binder,拿到所需的Binder后,就可以进行各自的操作了)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;

    import java.util.concurrent.CountDownLatch;

    /**
    * Binder连接池的客户端实现。
    * 这是一个采用单例模式设计的核心类,负责管理与远程BinderPoolService的连接,
    * 并作为客户端获取各种具体业务Binder的统一入口。
    * 它将异步的bindService过程封装成了同步的调用方式,简化了客户端的使用。
    */
    public class BinderPool {
    // 日志标签
    private static final String TAG = "BinderPool";

    // Binder代号:无效Binder
    public static final int BINDER_NONE = -1;
    // Binder代号:计算服务
    public static final int BINDER_COMPUTE = 0;
    // Binder代号:安全中心服务
    public static final int BINDER_SECURITY_CENTER = 1;

    // 应用上下文,使用getApplicationContext()防止内存泄漏
    private Context mContext;
    // 远程Binder池服务的代理对象,用于调用远程方法
    private IBinderPool mBinderPool;
    // BinderPool的唯一静态实例,volatile关键字确保多线程下的可见性
    private static volatile BinderPool sInstance;
    // 同步辅助工具,用于在连接建立完成前阻塞线程
    private CountDownLatch mConnectBinderPoolCountDownLatch;

    /**
    * 私有构造函数,确保只能通过getInstance()方法获取实例(单例模式)。
    * @param context 上下文对象
    */
    private BinderPool(Context context) {
    mContext = context.getApplicationContext();
    // 构造时立即开始连接服务
    connectBinderPoolService();
    }

    /**
    * 获取BinderPool的唯一实例(线程安全的双重检查锁定单例模式)。
    * @param context 上下文对象
    * @return BinderPool的单例
    */
    public static BinderPool getInstance(Context context) {
    if (sInstance == null) {
    // synchronized 锁就像一个单人房间,一次只允许一个线程进入,保证线程安全
    synchronized (BinderPool.class) {
    // 第二次检查,防止多个线程同时通过第一次检查后重复创建实例
    if (sInstance == null) {
    sInstance = new BinderPool(context);
    }
    }
    }
    return sInstance;
    }

    /**
    * 同步连接远程服务的方法。
    * 该方法会阻塞调用线程,直到与服务的连接成功建立。
    */
    private synchronized void connectBinderPoolService() {
    // 初始化一个计数为1的CountDownLatch,作为阻塞的“门闩”
    mConnectBinderPoolCountDownLatch = new CountDownLatch(1);
    Intent service = new Intent(mContext, BinderPoolService.class);
    // 异步绑定服务,绑定结果通过 mBinderPoolConnection 回调
    mContext.bindService(service, mBinderPoolConnection, Context.BIND_AUTO_CREATE);
    try {
    // 阻塞当前线程,等待门闩被打开(即等待onServiceConnected中的countDown()被调用)
    mConnectBinderPoolCountDownLatch.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    /**
    * 从Binder连接池中查询具体的业务Binder。
    * 这是提供给外部调用的核心方法。
    * @param binderCode 业务Binder的代号(如 BINDER_COMPUTE)
    * @return 对应的业务Binder接口;如果连接未建立或发生异常则返回null
    */
    public IBinder queryBinder(int binderCode) {
    IBinder binder = null;
    try {
    // 确保连接池代理不为空,然后发起跨进程调用
    if (mBinderPool != null) {
    binder = mBinderPool.queryBinder(binderCode);
    }
    } catch (RemoteException e) {
    // 捕获远程调用异常
    e.printStackTrace();
    }
    return binder;
    }

    /**
    * ServiceConnection的实现,用于监听与服务的连接状态。
    */
    private ServiceConnection mBinderPoolConnection = new ServiceConnection() {
    /**
    * 当与服务的连接成功建立时被回调(运行在主线程)。
    */
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    // 将返回的原始IBinder对象转换为我们定义的IBinderPool接口
    mBinderPool = IBinderPool.Stub.asInterface(service);
    try {
    // 设置死亡代理,监听远程Binder的死亡事件,增强健壮性
    mBinderPool.asBinder().linkToDeath(mBinderPoolDeathRecipient, 0);
    } catch (RemoteException e) {
    e.printStackTrace();
    }
    // 连接成功,打开“门闩”,唤醒所有等待的线程
    mConnectBinderPoolCountDownLatch.countDown();
    }

    /**
    * 当与服务的连接意外断开时被回调(例如服务进程崩溃)。
    * 注意:正常解绑不会触发此方法。
    */
    @Override
    public void onServiceDisconnected(ComponentName name) {
    // 此处可以添加重连逻辑
    }
    };

    /**
    * 死亡代理的实现。当远程服务进程意外死亡时,binderDied()方法会被回调。
    */
    private IBinder.DeathRecipient mBinderPoolDeathRecipient = new IBinder.DeathRecipient() {
    @Override
    public void binderDied() {
    Log.w(TAG, "binder died");
    // 1. 解除之前与已死亡Binder的死亡监听
    mBinderPool.asBinder().unlinkToDeath(mBinderPoolDeathRecipient, 0);
    // 2. 将持有的Binder代理置为空,防止误用
    mBinderPool = null;
    // 3. 立即尝试重新连接服务,实现自动恢复
    connectBinderPoolService();
    }
    };

    /**
    * 这是IBinderPool接口的服务端实现。
    * 它作为Binder连接池的“工厂”,根据客户端请求的binderCode,返回对应的具体业务Binder。
    * (通常这个类会放在服务端,这里放在一起是为了演示方便)
    */
    public static class BinderPoolImpl extends IBinderPool.Stub {
    public BinderPoolImpl() {
    super();
    }

    @Override
    public IBinder queryBinder(int binderCode) throws RemoteException {
    IBinder binder = null;
    // 使用switch-case结构分发不同的Binder实现
    switch (binderCode) {
    case BINDER_SECURITY_CENTER: {
    // 如果客户端请求安全中心,就创建一个SecurityCenterImpl实例
    binder = new SecurityCenterImpl();
    break;
    }
    case BINDER_COMPUTE: {
    // 如果客户端请求计算服务,就创建一个ComputeImpl实例
    binder = new ComputeImpl();
    break;
    }
    default:
    break;
    }
    return binder;
    }
    }
    }
  • 服务端实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public class BinderPoolService extends Service {
    private static final String TAG="BinderPoolService";
    //这一行代码的作用是创建并持有一个“Binder 管理员”的实例。

    //这个实例就是客户端在绑定服务后,第一个也是唯一一个直接交互的对象。
    private Binder mBinderPool=new BinderPool.BinderPoolImpl();

    @Override
    public void onCreate() {
    super.onCreate();
    }

    public BinderPoolService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
    Log.d(TAG, "onBind: ");
    return mBinderPool;
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    }
    }
  • 使用实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    private void doWork(){
    // 1. 获取 BinderPool 的单例实例。
    BinderPool binderPool=BinderPool.getInstance(this);
    // 2. 向远程服务查询用于安全加密的 Binder。
    IBinder securityBinder=binderPool.queryBinder(BinderPool.BINDER_SECURITY_CENTER);
    //3. 将底层的 IBinder 对象转换为我们定义的 AIDL 接口 ISecurityCenter。
    ISecurityCenter mSecurityCenter=(ISecurityCenter) SecurityCenterImpl.asInterface(securityBinder);
    //4.使用接口方法
    String msg="Android";
    System.out.println("content:"+msg);
    try {
    String password=mSecurityCenter.encrypt(msg);
    System.out.println("encrypt:"+password);
    System.out.println("decrypt:"+mSecurityCenter.decrypt(password));
    }catch (RemoteException e){
    e.printStackTrace();
    }
    Log.d(TAG, "visit ICompute");
    IBinder computeBinder=binderPool.queryBinder(BinderPool.BINDER_COMPUTE);
    ICompute mCompute=ComputeImpl.asInterface(computeBinder);
    try {
    System.out.println("3+5="+mCompute.add(3,5));
    }catch (RemoteException e){
    e.printStackTrace();
    }
    }