IPC机制--BinderPool
来源:互联网 发布:ios程序员烂大街 编辑:程序博客网 时间:2024/05/17 07:19
当很多模块都需要AIDL来进行跨进程通信,我们不可能为每一个AIDL创建Sevice,因此,我们可以采用BinderPool来托管我们的其他进程间通信接口,通过一些请求码对不同的进程间通信接口加以区分,在进行指定的进程间通信的时候,先从BinderPool中取出对应的Binder,利用其进行通信即可。利用这个方法,避免了多次创建Service,以及对系统资源的滥用,我们来看下如何实现BinderPo.ol机制。
首先,创建BinderPool的AIDL文件
// IBinderPool.aidlpackage com.example.no_clay.messagertest.BinderPool;// Declare any non-default types here with import statementsinterface IBinderPool { IBinder queryBinder(int binderCode);}
其次,其他AIDL文件的创建和接口完善
// ISecurityCenter.aidlpackage com.example.no_clay.messagertest.BinderPool;// Declare any non-default types here with import statementsinterface ISecurityCenter { String encrypt(String content); String decrypt(String password);}// ICompute.aidlpackage com.example.no_clay.messagertest.BinderPool;// Declare any non-default types here with import statementsinterface ICompute { int add(int a, int b);}
完善接口文件
package com.example.no_clay.messagertest.BinderPool;import android.os.RemoteException;/** * Created by no_clay on 2017/3/1. */public class ComputeImpl extends ICompute.Stub { @Override public int add(int a, int b) throws RemoteException { return a + b; }}package com.example.no_clay.messagertest.BinderPool;import android.os.RemoteException;/** * Created by no_clay on 2017/3/1. */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); }}
接下来是对BinderPool接口的实现
package com.example.no_clay.messagertest.BinderPool;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;/** * Created by no_clay on 2017/3/1. */public class BinderPool { private static final String TAG = "BinderPool"; //常量用于标志binder public static final int BINDER_NONE = -1; public static final int BINDER_COMPUTE = 0; public static final int BINDER_SECURITY_CENTER = 1; private Context mContext; private IBinderPool mBinderPool; //用于实现单例模式 private static volatile BinderPool sInstance; //同步工具类 private CountDownLatch mConnectBinderPoolCountDownLatch; private BinderPool(Context context) { mContext = context.getApplicationContext(); //连接服务 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 service = new Intent(mContext, BinderPoolService.class); mContext.bindService(service, mBinderPoolConnection, Context.BIND_AUTO_CREATE); try { mConnectBinderPoolCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } private ServiceConnection mBinderPoolConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBinderPool = IBinderPool.Stub.asInterface(service); try { mBinderPool.asBinder().linkToDeath(mBinderPoolDeathRecipient, 0); } catch (RemoteException e) { e.printStackTrace(); } mConnectBinderPoolCountDownLatch.countDown(); } @Override public void onServiceDisconnected(ComponentName name) { } }; //死亡代理 private IBinder.DeathRecipient mBinderPoolDeathRecipient = new IBinder.DeathRecipient() { @Override public void binderDied() { Log.w(TAG, "binderDied: "); mBinderPool.asBinder().unlinkToDeath(mBinderPoolDeathRecipient, 0); mBinderPool = null; connectBinderPoolService(); } }; public static class BinderPoolImpl extends IBinderPool.Stub { @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; } } /** * query binder by binderCode from binder pool * @param binderCode * @return */ public IBinder queryBinder(int binderCode) { IBinder binder = null; Log.d(TAG, "queryBinder: binderPool = " + (mBinderPool == null)); try { if (mBinderPool != null) { binder = mBinderPool.queryBinder(binderCode); } } catch (RemoteException e) { e.printStackTrace(); } return binder; }}
CountDownLatch
- 实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。
- 开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。
- 死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。
总结
这样以来我们就能在我们的应用中只建立一个Service就足够了。当我们添加一个AIDL接口的时候只需要在BinderPool中添加一个id,然后根据这个id,在BinderPoolImpl中创建一个对应的Binder对象即可。这样就很大程度上简化了我们的工作。
IPC方式的优缺点和适用场景
0 0
- IPC机制--BinderPool
- ipc机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- IPC机制
- Spring+SpringMVC+Hibernate整合
- Hello,java!
- HttpClient实现同步(sync)和异步(Async)
- srs gop缓冲
- [BZOJ3261][最大异或和][可持久化Trie]
- IPC机制--BinderPool
- 编程
- Android调试DJI大疆无人机方法
- git与svn的区别和其操作对比
- 不吃青春饭,关于程序员将来的发展方向
- 快速拨号的流程图
- 算法训练 最大最小公倍数
- MongoDB与Python调用
- Vim配置#pathogen插件管理工具