Binder连接池
一、为什么需要Binder线程池
产生原因:因为当有多个不同的业务块都要使用AIDL来进行通信,则需要创建多个Service,每创建一个Service就需要消耗系统资源。
解决思路:将所有的AIDL放在一个Service中处理
二、使用
具体原理:①、每个AIDL创建AIDL接口并用类实现此接口
②、然后创建一个主AIDL开放queryBinder接口,客户端输入int标识符来选择需要哪一个AIDL,来返回相对应的AIDL在服务器中的具体对象
③、服务器返回主AIDL类给客户端,这样客户端就能够调用主AIDL对象的queryBinder(int enum),获取需要的aidl
主要作用:将每个业务的AIDL请求统一转发给一个Service,避免Service的重建
具体使用:
前期准备:
假设有两个AIDL:
// ICompture.aidl package com.chen.android.testbinderpool.aidl; // Declare any non-default types here with import statements /*用来做加法计算的aidl*/ interface ICompture { int add(int a,int b); }
// ISecurityCenter.aidl package com.chen.android.testbinderpool.aidl; // Declare any non-default types here with import statements /*写入账号,密码的aidl*/ interface ISecurityCenter { String encrypt(String content); String decrypt(String password); }
创建IBinderPool.aidl:
package com.chen.android.testbinderpool.aidl; // Declare any non-default types here with import statements /*根据标识符,返回客户端需求的AIDL*/ interface IBinderPool { IBinder queryBinder(int binderCode); }
使用:
创建类继承并重写两个aidl接口
import android.os.RemoteException; /** * Created by PC on 2016/4/7. */ public class ComputeImpl extends ICompture.Stub { @Override public int add(int a, int b) throws RemoteException { return a+b; } }
public class SecurityConterImpl 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连接池:
1.单例模式:整个app只能创建一个对象
2.创建IBinderPool的静态类:重写接口
3.创建该类时候,自动连接Service
4.创建queryBinder()方法,能够调用IBinderPool的queryBinder()(因为服务器返回的Binder在BinderPool中)
public class BinderPool { //客户端通过标识符,获取相对应的Binder public static final int BINDER_SECURITY = 0; public static final int BINDER_COMPTURE = 1; private static BinderPool sBinderPool; private static Context mContext; private IBinderPool mIBinderPool; /*单例模式,在整个app中只会产生一个对象*/ private BinderPool(Context context) { mContext = context.getApplicationContext(); connectService(); } public static BinderPool getInstance(Context context){ synchronized (BinderPool.class) { if (sBinderPool == null) { sBinderPool = new BinderPool(context); } } return sBinderPool; } /*当客户端创建该对象时候,自动连接Service,不用客户端再自己动手了*/ private void connectService(){ ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //获取BinderPool对象 mIBinderPool = BinderPoolImpl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; Intent intent = new Intent(mContext,BinderPoolService.class); mContext.bindService(intent,connection,Context.BIND_AUTO_CREATE); } /*因为客户端没法收到从Service发送过来的Binder,利用该方法来执行Binder的方法*/ public IBinder queryBinder (int binderCode){ IBinder binder = null; if (mIBinderPool != null){ try { binder = mIBinderPool.queryBinder(binderCode); } catch (RemoteException e) { e.printStackTrace(); } } return binder; } /*继承IBinderPool接口,重写方法*/ public static class BinderPoolImpl extends IBinderPool.Stub{ @Override public IBinder queryBinder(int binderCode) throws RemoteException { IBinder binder; switch (binderCode){ case BINDER_COMPTURE: binder = new ComputeImpl(); break; case BINDER_SECURITY: binder = new SecurityConterImpl(); break; default: binder = null; break; } return binder; } } }
服务器端返回IBinderPool的Binder对象
public class BinderPoolService extends Service { private IBinder mIBinder; @Override public void onCreate() { super.onCreate(); //获取IBinderPool对象 mIBinder = new BinderPool.BinderPoolImpl(); } @Nullable @Override public IBinder onBind(Intent intent) { return mIBinder; } }