Android IPC之Binder连接池BinderPool

----------------------Android开发艺术探索学习之Binder连接池----------------------

通常情况下,在使用AIDL时,一个Service需要创建一个AIDL接口,在Service中创建一个类集成AIDL接口中的Stub并实现抽象方法,在onBind中返回该类实例,然后在Client中绑定服务,建立连接后可以访问Service中方法,即在一个Service中只能返回一个业务调用的Binder。

当多个业务模块都需要使用AIDL时(如50个,100个),如果创建多个Service会消耗大量的系统资源,使应用重量级,为了减少Service的数量,可以将多有的AIDL 放在一个Service中去管理。

具体是:每个业务模块创建自己的AIDL接口并实现该接口,向服务提供自己唯一的Binder对象,对于Service端,只提供一个Service,Service提供一个queryBinder的接口,这个接口可以根据具体的业务模块返回相应的Binder对象给客户端。

Binder连接池的主要作用是统一各个业务模块的Binder并统一转发到远程Service中去执行,避免重复创建Service.


具体使用过程:

服务端:服务端实现各个模块的AIDL接口和Binder



import android.os.RemoteException;

// 这是计算模块的Binder实现
public class ComputeImpl extends ICompute.Stub {
    @Override
    public int add(int a, int b) throws RemoteException {
        return a + b;
    }
}
import android.os.RemoteException;

// 这是加密模块的Binder实现
public class SecurityCenterImpl extends ISecurityCenter.Stub {
    private static final char SECRET_CODE = '^';
    @Override
    public String decrypt(String password) throws RemoteException {
        return encrypt(password);
    }

    @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);
    }
}
import android.os.IBinder;
import android.os.RemoteException;
// 这是BinderPool的Binder实现
public class BinderPoolImp extends IBinderPool.Stub {
    @Override
    public IBinder queryBinder(int binderCode) throws RemoteException {
        IBinder binder = null;
        switch (binderCode) {
            case 1: {
                binder = new SecurityCenterImpl();
                break;
            }
            case 2: {
                binder = new ComputeImpl();
                break;
            }
            default:
                break;
        }
        return binder;
    }
}
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;

public class BinderPoolService extends Service {
    private static final String TAG = "BinderPoolService";
    private Binder binder = new BinderPoolImp();
    @Override
    public void onCreate() {
        super.onCreate();
    }

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

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

这个Service的实现,在onBind中返回BinderPoolImpl实例。

然后是客户端

public class BinderPool {
    private final static String TAG = "BinderPool";
    private Context context;
    private IBinderPool binderPool;
    private static volatile BinderPool instance;

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

    public boolean isConnected() {
        return binderPool == null ? false : true;
    }

    private synchronized void connectBinderPoolService() {
        Intent intent = new Intent("com.raeyu.BINDER_POOL_SERVICE");
        intent.setPackage("com.example.raeyu.binderpool");
        context.bindService(intent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                binderPool = IBinderPool.Stub.asInterface(service);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        }, Context.BIND_AUTO_CREATE);
    }

    public static BinderPool getInstance(Context context) {
        if(instance == null) {
            synchronized (BinderPool.class) {
                if(instance == null) {
                    instance = new BinderPool(context);
                }
            }
        }
        return instance;
    }

    public IBinder queryBinder(int binderCode) {
        IBinder iBinder = null;
        try {
            iBinder = binderPool.queryBinder(binderCode);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return iBinder;
    }
}

客户端使用单例模式,具体使用:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        binderService();
    }

    private void binderService() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                BinderPool binderPool = BinderPool.getInstance(MainActivity.this);
                try {
                    sleep(1000);
                    IBinder security = binderPool.queryBinder(1);
                    Log.i("BinderPool", "onCreate: == " + security);
                    // 可以使用binder调用客户端的方法
                    ISecurityCenter securityCenter = ISecurityCenter.Stub.asInterface(security);
                    if(securityCenter != null) {
                        Log.i("BinderPool", "securityCenter: " + securityCenter.encrypt("hello world"));
                        Log.i("BinderPool", "securityCenter: " + securityCenter.decrypt("ni hao"));
                    }
                    IBinder compute = binderPool.queryBinder(2);
                    ICompute computeBinder = ICompute.Stub.asInterface(compute);
                    if(computeBinder != null)
                        Log.i("BinderPool", "computeBinder: " + computeBinder.add(2, 3));

                } catch (RemoteException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

输出结果:


这就是Binder连接池的使用!!!!!!!!!

猜你喜欢

转载自blog.csdn.net/yurhzzu/article/details/80669086