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();
            }
        }
    

      

posted on 2019-03-14 16:43  endian11  阅读(161)  评论(0编辑  收藏  举报

导航