Binder连接池
Posted Young_xiaoT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Binder连接池相关的知识,希望对你有一定的参考价值。
Binder连接池
首先回顾一下 AIDL 的 大致流程:首先创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Stub中的抽象方法,在Service的onBind方法中返回这个类的对象,然后客户端就可以绑定Service,建立连接就可以访问远程服务端的方法了。
如果有100个地方需要用到 AIDL ,需要创建100个 Service 吗?
答案是显而易见的,这时我们需要将AIDL放在同一个Service中去管理。
在这种模式下,整个工作机制是这样的:每个业务模块创建自己的 AIDL 接口并实现此接口,这个时候不同业务模块之间是不能有耦合的,所有的实现细节需要单独开来,然后向服务端提供一个唯一标识和其对应的 Binder 对象; 对于服务端来说,只需要一个 Service 就可以了,服务端提供一个 queryBinder 接口,这个接口会返回相应的 Binder对象。Binder 连接池的主要作用就是将每个业务模块的 Binder 请求统一转发到远程 Service 中去执行,从而避免了重复创建Service工程。
下面看一个简单的例子
1.提供两个 AIDL 接口 :ISecurityCenter 和 ICompute
// ISecurityCenter.aidl
interface ISecurityCenter
String encrypt(String content);
String decrypt(String password);
// ICompute.aidl
interface ICompute
int add(int a,int b);
2.实现这两个接口
public class SecurityCenterIml 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);
public class ComputeIml extends ICompute.Stub
@Override
public int add(int a, int b) throws RemoteException
return a + b;
3.为 Binder 连接池创建AIDL接口 IBinderPool.aidl
// IBinderPoll.aidl
interface IBinderPool
IBinder queryBinder(int binderCode);
4.为Binder连接池创建远程Service并实现IBinderPool
@Override
public IBinder queryBinder(int binderCode) throws RemoteException
IBinder binder = null;
switch (binderCode)
case BINDER_SECURITY_CENTER:
binder = new SecurityCenterIml();
break;
case BINDER_COMPUTE:
binder = new ComputeIml();
break;
default:
break;
return binder;
当Binder连接池连接上远程服务时,会根据不同模块的标识即binderCode返回不同的Binder对象,通过这个Binder对象所执行的操作全部发生在远程服务端。
5.Service 的实现比较简单
public class BinderPoolService extends Service
private static final String TAG = "BinderPoolService";
private Binder mBinderPool = new BinderPool.BinderPoolImpl();
@Override
public void onCreate()
super.onCreate();
@Override
public IBinder onBind(Intent intent)
Log.d(TAG, "onBind");
return mBinderPool;
@Override
public void onDestroy()
super.onDestroy();
6.Binder连接池内部需要去绑定远程服务,绑定成功后服务端就可以通过它的queryBinder方法去获取对应的Binder。
public class BinderPool
public static final int BINDER_SECURITY_CENTER = 1;
public static final int BINDER_NONE = -1;
public static final int BINDER_COMPUTE = 0;
private Context mContext;
private IBinderPool mBinderPool;
private static volatile BinderPool sInstance;
private CountDownLatch mConnectBinderPoolCountDownLatch;
private IBinder.DeathRecipient mBinderPoolDeathRecipient = new IBinder.DeathRecipient()
@Override
public void binderDied()
mBinderPool.asBinder().unlinkToDeath(mBinderPoolDeathRecipient,0);
mBinderPool = null;
connectBinderPoolService();
;
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 BinderPool(Context context)
mContext = context.getApplicationContext();
connectBinderPoolService();
private synchronized void connectBinderPoolService()
mConnectBinderPoolCountDownLatch = new CountDownLatch(1);
Intent intent = new Intent(mContext,BinderPoolService.class);
mContext.bindService(intent,mBinderPoolConnection,Context.BIND_AUTO_CREATE);
try
mConnectBinderPoolCountDownLatch.await();
catch (InterruptedException e)
e.printStackTrace();
public IBinder queryBinder(int bindService)
IBinder binder = null;
if (mBinderPool != null)
try
binder = mBinderPool.queryBinder(bindService);
catch (RemoteException e)
e.printStackTrace();
return binder;
public static BinderPool getsInstance(Context context)
if (sInstance == null)
synchronized (BinderPool.class)
if (sInstance == null)
sInstance = new BinderPool(context);
return sInstance;
public static class BinderPoolIml extends IBinderPool.Stub
@Override
public IBinder queryBinder(int binderCode) throws RemoteException
IBinder binder = null;
switch (binderCode)
case BINDER_SECURITY_CENTER:
binder = new SecurityCenterIml();
break;
case BINDER_COMPUTE:
binder = new ComputeIml();
break;
default:
break;
return binder;
7.客户端代码
public class BinderPoolActivity extends AppCompatActivity
private ISecurityCenter mSecurityCenter;
private ICompute mCompute;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_binder_pool);
new Thread(new Runnable()
@Override
public void run()
doWork();
).start();
private void doWork()
BinderPool binderPool = BinderPool.getsInstance(BinderPoolActivity.this);
IBinder securityBinder = binderPool.queryBinder(BinderPool.BINDER_SECURITY_CENTER);
mSecurityCenter = SecurityCenterIml.asInterface(securityBinder);
String msg = "Hello 安卓";
try
String password = mSecurityCenter.encrypt(msg);
Logger.i("encrypt:" + password);
Logger.i("decrypt:" + mSecurityCenter.decrypt(password));
catch (RemoteException e)
e.printStackTrace();
IBinder computeBinder = binderPool.queryBinder(BinderPool.BINDER_COMPUTE);
mCompute = ComputeIml.asInterface(computeBinder);
try
Logger.i("add 3 + 5 :" + mCompute.add(3, 5) + "");
catch (RemoteException e)
e.printStackTrace();
Log
╔════════════════════════════════════════════════════════════════════════════════════════
║ Thread: Thread-245
╟────────────────────────────────────────────────────────────────────────────────────────
║ BinderPoolActivity.access$000 (BinderPoolActivity.java:11)
║ BinderPoolActivity.doWork (BinderPoolActivity.java:39)
╟────────────────────────────────────────────────────────────────────────────────────────
║ encrypt:;221~寗匍
╚════════════════════════════════════════════════════════════════════════════════════════
╔════════════════════════════════════════════════════════════════════════════════════════
║ Thread: Thread-245
╟────────────────────────────────────────────────────────────────────────────────────────
║
║ BinderPoolActivity.doWork (BinderPoolActivity.java:40)
╟────────────────────────────────────────────────────────────────────────────────────────
║ decrypt:Hello 安卓
╚════════════════════════════════════════════════════════════════════════════════════════ ╔════════════════════════════════════════════════════════════════════════════════════════
║ Thread: Thread-245
╟────────────────────────────────────────────────────────────────────────────────────────
║ BinderPoolActivity.access$000 (BinderPoolActivity.java:11)
║ BinderPoolActivity.doWork (BinderPoolActivity.java:49)
╟────────────────────────────────────────────────────────────────────────────────────────
║ add 3 + 5 :8
╚════════════════════════════════════════════════════════════════════════════════════════
这样如果有新业务需要加新的 AIDL ,那么实现它自己的 AIDL 接口后,只需要修改 BinderPoolIml 中的 queryBinder 方法,给自己添加一个新的 binderCode 并返回对应的 Binder 对象即可。
另一张表格来说明如何选择合适的 IPC 方式
以上是关于Binder连接池的主要内容,如果未能解决你的问题,请参考以下文章