Binder连接池

内容参考自《Android开发艺术探索》

Binder连接池

  • 工作机制:每个业务模块创建自己的AIDL接口并实现此接口,这个时候不同业务模块之间时不能有耦合的,所有实现细节都要单独开来,然后向服务端提供自己的唯一标识和其对应的Binder对象。
  • Binder连接池的主要作用就是将每个业务模块的Binder请求统一转发到远程Service中去执行,从而避免了重复创建Service的过程,极大提高了AIDL的开发效率。

一、 Binder连接池的创建

  • 实现Binder连接池的步骤

    1. 创建ADIL
    2. 实现各AIDL接口
    3. 服务端实现
    4. 连接池的实现
    5. 客户端的实现
    6. 在AndroidManifest.xml中注册服务
  • 创建ADIL

// ISecurityCenter.aidl
interface ISecurityCenter {
    String encrypt(String content);
    String decrypt(String password);
}
// ICompute.aidl
interface ICompute {
    int add(int a, int b);
}
// IBinderPool.aidl
interface IBinderPool {
    IBinder queryBinder(int binderCode);
}
  • 实现各AIDL接口
// SecurityCenterImpl.java
public class SecurityCenterImpl extends ISecurityCenter.Stub {
    private static final char SECRET_CODE = '^';
    @Override
    public String encrypt(String content) throws RemoteException {
        char[] charArr = content.toCharArray();
        for (int i = 0; i < charArr.length ; i++) {
            charArr[i] ^= '^';
        }
        return new String(charArr);
    }

    @Override
    public String decrypt(String password) throws RemoteException {
        char[] charArr = password.toCharArray();
        for (int i = 0; i < charArr.length ; i++) {
            charArr[i] ^= '^';
        }
        return new String(charArr);
    }
}
// ComputeImpl.java
public class ComputeImpl extends ICompute.Stub {
    @Override
    public int add(int a, int b) throws RemoteException {
        return a+b;
    }
}
// BinderPoolImpl.java
public  class BinderPoolImpl extends IBinderPool.Stub {
    public static final int BINDER_COMPUTE = 0;
    public static final int BINDER_SECURITY_CENTER = 1;

    @Override
    public IBinder queryBinder(int binderCode) throws RemoteException {
        IBinder binder = null;
        switch (binderCode) {
            case BINDER_SECURITY_CENTER:
                binder = new SecurityCenterImpl();
                break;
            case BINDER_COMPUTE:
                binder = new ComputeImpl();
                break;
            default:
                break;
        }
        return binder;
    }
}
  • 服务端实现
// BinderPoolService.java
public class BinderPoolService extends Service {
    private Binder mBinderPoolImpl = new BinderPoolImpl();
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinderPoolImpl;
    }
}
  • 连接池的实现
// BinderPool.java
public class BinderPool {
    private static final String TAG = "BinderPool";

    private Context mContext;
    private IBinderPool mBinderPoolImpl;
    private static volatile BinderPool sInstance;
    private CountDownLatch mConnectBinderPoolCountDownLatch;

    private BinderPool(Context context) {
        mContext = context;
        connectBinderPoolService();
    }

    public static BinderPool getInstance(Context context){
        if (sInstance == null) {
            synchronized (BinderPool.class) {
                if (sInstance == null) {
                    sInstance = new BinderPool(context);
                }
            }
        }
        return sInstance;
    }
    private synchronized void connectBinderPoolService() {
        mConnectBinderPoolCountDownLatch = new CountDownLatch(1);
        Intent intent = new Intent(mContext, BinderPoolService.class);
        mContext.bindService(intent, mBinderPoolConnection, Context.BIND_AUTO_CREATE);
        try {
            // 当前线程进入等待,直到主线程onServiceConnected执行完毕,则该线程唤醒
            mConnectBinderPoolCountDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public IBinder queryBinder(int binderCode) {
        IBinder binder = null;

        try {
            if (mBinderPoolImpl != null) {
                binder = mBinderPoolImpl.queryBinder(binderCode);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return binder;
    }

    private ServiceConnection mBinderPoolConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinderPoolImpl = IBinderPool.Stub.asInterface(service);
            try {
                mBinderPoolImpl.asBinder().linkToDeath(mBinderPoolDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            // 计数减1,当计数为0时唤醒被它阻塞的线程
            mConnectBinderPoolCountDownLatch.countDown();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    private IBinder.DeathRecipient mBinderPoolDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            Log.d(TAG, "binderDied: ");
            mBinderPoolImpl.asBinder().unlinkToDeath(mBinderPoolDeathRecipient, 0);
            mBinderPoolImpl = null;
            connectBinderPoolService();
        }
    };
}
  • 客户端实现
// MainActivity.java
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private ISecurityCenter mSecurityCenter;
    private ICompute mCompute;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                doWork();
            }
        }).start();
    }

    private void doWork() {
        Log.d(TAG, "this: " + this);
        Log.d(TAG, "MainActivity.this: " + MainActivity.this);
        BinderPool binderPool = BinderPool.getInstance(MainActivity.this);
        IBinder securityBinder = binderPool.queryBinder(BinderPoolImpl.BINDER_SECURITY_CENTER);
        mSecurityCenter = SecurityCenterImpl.asInterface(securityBinder);
        Log.d(TAG, "visit ISecurityCenter");
        String msg = "helloworld-安卓";
        Log.d(TAG, "content: " + msg);
        try {
            String password = mSecurityCenter.encrypt(msg);
            Log.d(TAG, "encrypt: " + password);
            Log.d(TAG, "decrypt: " + mSecurityCenter.decrypt(password));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "visit ICompute");
        IBinder computeBinder = binderPool.queryBinder(BinderPoolImpl.BINDER_COMPUTE);
        mCompute = ComputeImpl.asInterface(computeBinder);
        try {
            Log.d(TAG, "3+5 = " + mCompute.add(3, 5));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}
  • 在AndroidManifest.xml中注册服务
<service android:name=".BinderPoolService"
    android:process=":remote"/>

二、 Binder连接池的工作流程

Binder连接池工作流程

  • 这个过程好比于你(Client)打电话给10086(Service),然后转接到人工服务,此时某位客服(mBinderPoolImpl)接了你的电话,你跟客服说宽带对的但就是连不上,然后客服根据你的情况(mBinderPoolImpl.queryBinder()RPC)把线路转接给了宽带技术客服(mClientNeededBinder),后来你让宽带技术客服检查和重置宽带的连接状态(mNeededBinder.xxxMethod()RPC),顺利的解决了问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值