Binder连接池
- ServiceConncetion的两个回调方法是运行在主线程的 (一般回调方法看运行在那个线程,就是它在回调的时候所在的线程)
- 并发编程CountDownLatch的使用
- Binder连接池示例代码:
public class BinderPool { private static final String TAG = "BinderPool"; public static final int BINDER_NONE = -1; public static final int BINDER_COMPUTE = 0; public static final int BINDER_SECURITY_CENTER = 1; private static volatile BinderPool ourInstance ; private IBinderPool binderPool; private CountDownLatch mConnectBinderPoolCountDownLatch = null; private Context mContext; private ServiceConnection mBinderPoolConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i(TAG, "onServiceConnected: "+Thread.currentThread().getName()); binderPool = IBinderPool.Stub.asInterface(service); try { binderPool.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: " ); binderPool.asBinder().unlinkToDeath(mBinderPoolDeathRecipient,0); binderPool = null; connectBinderPoolService(); } }; static BinderPool getInstance(Context context) { if (ourInstance == null){ synchronized (BinderPool.class){ if (ourInstance == null){ ourInstance = new BinderPool(context); } } } return ourInstance; } private BinderPool(Context context) { this.mContext = context.getApplicationContext(); connectBinderPoolService(); } private synchronized void connectBinderPoolService() { Log.i(TAG, "connectBinderPoolService: "+Thread.currentThread().getName()); mConnectBinderPoolCountDownLatch = new CountDownLatch(1); Intent intent = new Intent(mContext,BinderPoolService.class); mContext.bindService(intent,mBinderPoolConnection,Context.BIND_AUTO_CREATE); try { mConnectBinderPoolCountDownLatch.await();//会阻塞当前线程,直到计数为0 } catch (InterruptedException e) { e.printStackTrace(); } } public IBinder queryBinder(int binderCode){ Log.i(TAG, "queryBinder: "); IBinder binder = null; if (binderPool != null){ try { Log.i(TAG, "queryBinder: "); binder = binderPool.queryBinder(binderCode); } catch (RemoteException e) { e.printStackTrace(); } } return binder; } public static class BinderPoolImpl extends IBinderPool.Stub { private static final String TAGa= "BinderPoolImpl"; public BinderPoolImpl() { super(); } @Override public IBinder queryBinder(int binderCode) throws RemoteException { IBinder ibinder = null; switch (binderCode){ case BINDER_COMPUTE: ibinder = new ComputeImpl(); break; case BINDER_NONE: break; case BINDER_SECURITY_CENTER: ibinder = new SecurityCenterImpl(); break; } return ibinder; } } }
// IBinderPool.aidl package com.lzw.cha01.myapplication.chapter2.binderpool; // Declare any non-default types here with import statements interface IBinderPool { IBinder queryBinder(int binderCode); }
// ICompute.aidl package com.lzw.cha01.myapplication.chapter2.binderpool; // Declare any non-default types here with import statements interface ICompute { int add(int a, int b); }
// ISecurityCenter.aidl package com.lzw.cha01.myapplication.chapter2.binderpool; // Declare any non-default types here with import statements interface ISecurityCenter { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ String encrypt(String content); String decrypt(String password); }
public class ComputeImpl extends ICompute.Stub { @Override public int add(int a, int b) throws RemoteException { return a+b; } }
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); } }
new Thread() { @Override public void run() { super.run(); doWork(); } }.start(); private void doWork() { BinderPool binderPool = BinderPool.getInstance(BinderPoolAct.this); IBinder securityBinder = binderPool.queryBinder(BinderPool.BINDER_SECURITY_CENTER); mCenter = SecurityCenterImpl.asInterface(securityBinder); Log.d(TAG, "doWork: visit Security Center"); String msg = "Hello World - Android"; Log.d(TAG, "doWork: " + msg); try { String password = mCenter.encrypt(msg); Log.i(TAG, "doWork: pwd="+password); Log.d(TAG, "doWork: decrypt " + mCenter.decrypt(password)); } catch (RemoteException e) { e.printStackTrace(); } }
Dana.Lee
To:Dana_Lee1016@126.com