Android IPC进程间通信(七) Binder连接池

Binder管家之Binder连接池

IPC进程间通信(四)之AIDL中的AIDL由一个Service进行管理,若是创建10个AIDL业务模块是不是也要创建10个Service来进行管理,那100个呢?显然繁琐,怎么办么,用Binder连接池呀!
工作机制:
1.每个业务模块创建其AIDL接口并实现此接口生成具有唯一标识的Binder。
2.Binder连接池将每个业务模块的Binder统一转发给远程Service。
3.远程Service只需创建一个,并提供一个queryBinder接口,此接口根据业务模块的标识来返回相应的Binder给客户端,客户端即可进行远程方法调用。
一,创建业务模块AIDL

package com.example.binderpooltest;
//加法功能
interface IPlus {
    int plus(int a,int b);
}
package com.example.binderpooltest;
//乘法功能
interface IMultiply {
    int multiply(int a,int b);
}

创建一个连接池的AIDL接口queryBinder用于根据业务模块的标识来返回相应的Binder给请求者

package com.example.binderpooltest;

//连接池依binderCode查询Binder的接口
interface IBinderPool {
   IBinder queryBinder(int binderCode);
}

二,创建子类继承自己的AIDL生成Binder
命名规则 xxImple
先make project 一下生成AIDL对应的 xxx.java文件
路径\app\build\generated\source\aidl\debug\包名\xxx.java

package com.example.binderpooltest;
import android.os.RemoteException;

/**
 * 实现AIDL业务模块的Binder
 * IPlus为自定义AIDL生成的java类
 * public static abstract class Stub extends android.os.Binder implements com.example.binderpooltest.IPlus
 * Stub继承自Binder所以IPlus.Stub即为Binder
 * 所以IPlusImple也是一个Binder
 */
public class IPlusImple extends IPlus.Stub {

    @Override
    public int plus(int a, int b) throws RemoteException {
        return a + b;
    }
}
package com.example.binderpooltest;
import android.os.RemoteException;

public class IMultiplyImple extends IMultiply.Stub {

    @Override
    public int multiply(int a, int b) throws RemoteException {
        return a * b;
    }
}

三,创建BinderPool类作为连接池
知识点:
1.双锁实现单实例
2.共享锁CountDownLatch实现同步
3.IBinder.DeathRecipient实现服务断开重连

public class BinderPool {

    private static final String TAG = "DEBUG-WCL: " + BinderPool.class.getSimpleName();

    public static final int BINDER_CODE_ONE = 0;
    public static final int BINDER_CODE_TWO = 1;

    //自定义ADIL生成的IBinderPool.java类
    private IBinderPool mBinderPool;
    //第一锁volatile全局可见
    private static volatile BinderPool sInstance;
    private Context mContext;
    // 同步机制
    private CountDownLatch mCountDownLatch;

    private BinderPool(Context context) {
        mContext = context.getApplicationContext();
        connectBinderPoolService();
    }

    // 单例
    public static BinderPool getInstance(Context context) {
        if (sInstance == null) {
            //第二锁synchronized
            synchronized (BinderPool.class) {
                if (sInstance == null) {
                    sInstance = new BinderPool(context);
                }
            }
        }
        return sInstance;
    }

    // Binder的服务连接
    private ServiceConnection mBinderPoolConnection = new ServiceConnection() {
        @Override public void onServiceConnected(ComponentName name, IBinder service) {
            //以服务返回的IBinderPoolImple-Binder生成IBinderPool对象
            mBinderPool = IBinderPool.Stub.asInterface(service);
            try {
                mBinderPool.asBinder().linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            //设置次数减一,此时为零,下一个开始连接
            mCountDownLatch.countDown();
        }

        @Override public void onServiceDisconnected(ComponentName name) {

        }
    };

    // 绑定服务池
    private synchronized void connectBinderPoolService() {
        //排队连接,设置调用一次countDown()后,前一个连接断开,后一个开始连接
        mCountDownLatch = new CountDownLatch(1);
        Intent service = new Intent(mContext, BinderService.class);
        mContext.bindService(service, mBinderPoolConnection, Context.BIND_AUTO_CREATE);
        try {
            //其余等待
            mCountDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 失效重联机制, 当Binder死亡时, 重新连接
    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override public void binderDied() {
            Log.d(TAG, "Binder失效");
            mBinderPool.asBinder().unlinkToDeath(mDeathRecipient, 0);
            mBinderPool = null;
            connectBinderPoolService();
        }
    };


    /**
     * 用于被客户端调用,请求Binder  ,最终为向服务端请求
     * 此时的mBinderPool为链接服务时从服务返回的IBinderPoolImple-Binder生成的IBinderPool接口
     * 即可调用接口方法queryBinder(binderCode)即回掉到IBinderPoolImple.queryBinder(int binderCode)
     * @param binderCode binder代码
     * @return Binder
     */
    public IBinder queryForBinder(int binderCode) {
        IBinder binder = null;
        try {
            if (mBinderPool != null) {
                binder = mBinderPool.queryBinder(binderCode);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return binder;
    }

    /**
     * 用于被服务端调用,运行与服务端,当客户端向BinderPool发起Binder请求,BinderPool向服务请求,返回Binder给客户端
     * public static abstract class Stub extends android.os.Binder implements com.example.binderpooltest.IBinderPool
     * IBinderPool.Stub实现了AIDL接口IBinderPool
     * IBinderPoolImple继承IBinderPool.Stub,所以IBinderPoolImple重写了AIDL接口方法,若其他地方调用
     * IBinderPool.queryBinder(binderCode)即会回调到此方法
     */
    public static class IBinderPoolImple extends IBinderPool.Stub {

        @Override
        public IBinder queryBinder(int binderCode) throws RemoteException {

            IBinder iBinder = null;
            switch (binderCode) {
                case BINDER_CODE_ONE:
                    iBinder = new IPlusImple();
                    break;
                case BINDER_CODE_TWO:
                    iBinder = new IMultiplyImple();
                    break;
            }
            return iBinder;
        }
    }
}

四,创建服务用于管理BinderPool发送过来的Binder

public class BinderService extends Service {

    public BinderService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }
	//调用BinderPool中的,AIDL查询接口queryBinder的实现类,其中实现了依binderCode返回Binder的方法
	//将此IBinder返回给BinderPool
    private IBinder mBinder = new BinderPool.IBinderPoolImple();

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

五,前台客户端实现

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    //请求Binder的唯一标识
    public static final int METHOD_CODE_ONE = 1;
    public static final int METHOD_CODE_TWO = 2;
    private Context mContext;
    private BinderPool mBinderPool;
    //请求并希望返回的IBinder
    private IBinder mPlusBinder;
    private IBinder mMultuplyBinder;
    //以返回的IBinder创建的接口
    private IPlus mIPlus;
    private IMultiply mIMultiply;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = getApplicationContext();
        new Thread(new doWork()).start();
    }

    private class doWork implements Runnable {
        public doWork() {
            super();
        }

        @Override
        public void run() {
            int a = 2;
            int b = 5;
            Log.d(TAG, "doWork: 1");
            //创建BinderPool单实例
            mBinderPool = BinderPool.getInstance(mContext);
            Log.d(TAG, "doWork: 2");
            try {
                //请求的IBinder
                mPlusBinder = mBinderPool.queryForBinder(METHOD_CODE_ONE);
                Log.d(TAG, "doWork: 3");
                //以返回的IBinder创建接口
                mIPlus = IPlusImple.asInterface(mPlusBinder);
                //调用远程方法
                int result1 = mIPlus.plus(a, b);
                mMultuplyBinder = mBinderPool.queryForBinder(METHOD_CODE_TWO);
                mIMultiply = IMultiplyImple.asInterface(mMultuplyBinder);
                int result2 = mIMultiply.multiply(a, b);
                Toast.makeText(mContext, "a + b = " + result1 + "/n" +
                        "a × b = " + result2, Toast.LENGTH_SHORT).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39507260/article/details/83869997