池的這個概念是典型的享元設計模式。比如數據庫連接池,線程池。對於有限的資源,我們用一個池去管理,讓資源共享於不現調用者之間。
這裏Binder連接池就是爲了解決需要多個aidl服務時,我們可以把這些aidl接口放在池中,讓service直接提供池的接口,而在客戶端同樣用一個池的處理類去與service綁定,調用者根據需求去操控池去調用不同接口既可。
藝術探索這本書中把服務端與調用端寫在一起,特別是BinderPool這部分的客戶端與服務端部分耦合在一起,這裏做下分離及改進。@singwhatiwanna
實現步驟:
服務端
1. 提供被調用的aidl接口
2. 實現一個BinderPool池的aidl接口,裏面有一個queryBinder方法
3. 實現上述的aidl接口
4. Service返回 BinderPoolImpl
客戶端
1.客戶端實現一個調用池BindPool,綁定服務,並提供queryBinder方法返回對應的binder.
2.客戶端Activity操縱BindPool調用不現的aidl
具體實現如下,首選 是兩個aidl接口
package mytest.jiang.wei.ipc.bindpool;
interface ICompute {
int add(int a, int b);
}
package mytest.jiang.wei.ipc.bindpool;
interface ISecurityCenter {
String encrypt(String content);
String decrypt(String password);
}
IBinderPool,返回值是aidl本身
package mytest.jiang.wei.ipc.bindpool;
import android.os.IBinder;
interface IBindPool {
IBinder queryBind(int binderCode);
}
BinderPoolImpl,
public class BinderPoolImpl extends IBindPool.Stub {
@Override
public IBinder queryBind(int binderCode) throws RemoteException {
IBinder binder = null;
switch (binderCode) {
case BINDER_SECURITY_CENTER :
binder = new SecurityCenterImpl();
break;
case BIND_COMPUTE:
binder = new ComputeImpl();
break;
default:
break;
}
return binder;
}
}
Service中返回BinderPoolImpl
public class BinderPoolService extends Service{
private Binder mBinderPool = new BinderPool.BinderPoolImpl();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinderPool;
}
}
下面看Client端,這裏新建另外一個Module, BinderPool一般從簡,我去掉了監聽連接狀態的部分,注意這裏一定要提供unBind的方法,
public class BinderPool {
private final Context mContext;
private static volatile BinderPool instantce;
private static IBindPool mBinderPool;
private BinderPool(Context context) {
mContext = context;
connectBinderPoolService();
}
public static BinderPool getInstance(Context context) {
if (instantce == null) {
synchronized (BinderPool.class) {
if (instantce == null) {
instantce = new BinderPool(context);
}
}
}
return instantce;
}
private void connectBinderPoolService() {
Intent service = new Intent("com.wei.jiang.binderpool");
//5.0後的service必須以顯式意圖去調用,這裏通過設置包名轉爲顯式意圖
service.setPackage("mytest.jiang.wei.ipc");
mContext.bindService(service, mBinderPoolConnction, Context.BIND_AUTO_CREATE);
}
public IBinder queryBinder(int binderCode) {
IBinder binder = null;
if (mBinderPool != null) {
try {
binder = mBinderPool.queryBind(binderCode);
} catch (RemoteException e) {
e.printStackTrace();
}
}
return binder ;
}
private ServiceConnection mBinderPoolConnction = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBinderPool = IBindPool.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
public void unBind() {
mContext.unbindService(mBinderPoolConnction);
}
}
Activity,在onDestory中去解綁服務,不然會報錯
public class MainActivity extends Activity{
private BinderPool binderPool;
@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() {
binderPool = BinderPool.getInstance(this);
IBinder securityBinder = binderPool.queryBinder(BinderPool.BINDER_SECURITY_CENTER);
ISecurityCenter securityCenter = ISecurityCenter.Stub.asInterface(securityBinder);
IBinder computeBinder = binderPool.queryBinder(BinderPool.BIND_COMPUTE);
ICompute computeImpl = ICompute.Stub.asInterface(computeBinder);
String msg = "hello world";
System.out.println(msg);
try {
String password= securityCenter.encrypt(msg);
System.out.println(password);
System.out.println(securityCenter.decrypt(password));
System.out.println(computeImpl.add(1, 2));
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
binderPool.unBind();
}
}