Binder线程池
来源:互联网 发布:windows 8.1系统镜像 编辑:程序博客网 时间:2024/06/01 17:45
上一篇水文介绍了IPC的几种方式,几乎都是一对一的方式。本节,再次探讨AIDL的使用,例如多个业务都需要使用AIDL时,我们不能对每个都写一个Service吧,10个也许能写,那100个呢?所以,换种思路。
前方高能,又是一篇“水”文,O(∩_∩)O哈哈~,主要是简单的Binder线程池用法和IPC各种方式的优缺点。
详细代码见Binder线程池
线程池机制
大致流程
每个业务模块创建自己的AIDL接口并实现此接口,这个时候不同业务模块之间不能有耦合,所有实现细节单独开来,然后向服务端提供自己的唯一标识和其对应的Binder对象;对于服务端而言,只需要一个Service就可以了,服务端提供一个queryBinder接口,这个接口能够根据业务模块的特征来返回相应的Binder对象给它们,不同的业务模块拿到所需的Binder对象后就可以进程远程方法调用了。由此可见,Binder线程池的主要作用就是将每个业务模块的Binder请求统一转发到远程Servie中去执行,从而避免了重复创建Service的过程,工作原理如图
下面用代码模拟实现下。
我们创建两个AIDL接口(ISecurityCenter和ICompute)来模拟两个业务,多个时类似,增加对应接口即可。
ISecurityCenter.aidl
// ISecurityCenter.aidlpackage com.breezehan.ipc.binderpool;interface ISecurityCenter { String encrypt(String content); String decrypt(String password);}
ICompute.aidl
// ICompute.aidlpackage com.breezehan.ipc.binderpool;interface ICompute { int add(int a,int 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); }}public class ComputeImpl extends ICompute.Stub { @Override public int add(int a, int b) throws RemoteException { return a + b; }}
业务模块都有了,我们要创建一个Binder连接池需要的AIDL,这里是一个代理或工厂,根据标识返回对应Binder
// IBinderPool.aidlpackage com.breezehan.ipc.binderpool;interface IBinderPool { IBinder queryBinder(int binderCode);}
在连接池中实现,根据标识返回不同Binder
static class BinderPoolImpl extends IBinderPool.Stub { @Override public IBinder queryBinder(int binderCode) throws RemoteException { IBinder binder =null; switch (binderCode) { case BINDER_COMPUTE: binder = new ComputeImpl(); break; case BINDER_SECURITY_CENTER: binder = new SecurityCenterImpl(); break; } return binder; }}
Service比较简单,逻辑处理都放在Binder线程池中
package com.breezehan.ipc.binderpool;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class BinderPoolService extends Service { private static final String TAG = "BinderPoolService"; private IBinder binderPool = new BinderPool.BinderPoolImpl(); public BinderPoolService() { } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind"); return binderPool; } @Override public void onDestroy() { super.onDestroy(); }}
Binder线程池的具体实现,同时需处理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 sInstance;//确保并发取值正确性 private final Context mContext; //控制多个线程时,某一线程中代码执行顺序;是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行 private CountDownLatch mConnectBinderPoolCountDownLatch; private IBinderPool mBinderPool; public BinderPool(Context context) { mContext = context.getApplicationContext(); connectBinderPoolService(); } private void connectBinderPoolService() { mConnectBinderPoolCountDownLatch = new CountDownLatch(1); Intent service = new Intent(mContext, BinderPoolService.class); mContext.bindService(service, mServiceConnection, Context.BIND_AUTO_CREATE); try { mConnectBinderPoolCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } public static BinderPool getInstance(Context context) { if (sInstance == null) { synchronized (BinderPool.class) { if (sInstance == null) { sInstance = new BinderPool(context); } } } return sInstance; } private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBinderPool = IBinderPool.Stub.asInterface(service); try { mBinderPool.asBinder().linkToDeath(mBinderDeathRecipient, 0); } catch (RemoteException e) { e.printStackTrace(); } mConnectBinderPoolCountDownLatch.countDown(); } @Override public void onServiceDisconnected(ComponentName name) { } }; private IBinder.DeathRecipient mBinderDeathRecipient = new IBinder.DeathRecipient() { @Override public void binderDied() { Log.w(TAG, "binderDied: "); mBinderPool.asBinder().unlinkToDeath(mBinderDeathRecipient, 0); mBinderPool = null; connectBinderPoolService(); } }; public IBinder queryBinder(int bindCode) { IBinder binder = null; try { binder = mBinderPool.queryBinder(bindCode); } catch (RemoteException e) { e.printStackTrace(); } return binder; } static class BinderPoolImpl extends IBinderPool.Stub { @Override public IBinder queryBinder(int binderCode) throws RemoteException { IBinder binder =null; switch (binderCode) { case BINDER_COMPUTE: binder = new ComputeImpl(); break; case BINDER_SECURITY_CENTER: binder = new SecurityCenterImpl(); break; } return binder; } }}
Activity中模拟使用。此处我只使用了其中一个Binder。
public class BinderPoolActivity extends AppCompatActivity { private static final String TAG = "BinderPoolActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_binder_pool); new Thread(new Runnable() { @Override public void run() { doWork(); } }).start(); } private void doWork() { BinderPool binderPool = BinderPool.getInstance(BinderPoolActivity.this); IBinder securityBinder = binderPool.queryBinder(BinderPool.BINDER_SECURITY_CENTER);// ISecurityCenter iSecurityCenter = ISecurityCenter.Stub.asInterface(securityBinder); ISecurityCenter iSecurityCenter = SecurityCenterImpl.asInterface(securityBinder); Log.d(TAG, "visit ISecurityCenter"); String msg = "helloworld-安卓"; try { String encrypt = iSecurityCenter.encrypt(msg); Log.d(TAG, "doWork,encrypt:"+encrypt); Log.d(TAG, "doWork,decrypt:"+iSecurityCenter.decrypt(encrypt)); } catch (RemoteException e) { e.printStackTrace(); } IBinder computeBinder = binderPool.queryBinder(BinderPool.BINDER_COMPUTE); ICompute iCompute = ComputeImpl.asInterface(computeBinder); try { Log.d(TAG, "doWork,compute: "+iCompute.add(1,2)); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); }}
基本思想如上,改进或者多个Binder根本不变,添枝加叶即可。
选中合适的IPC方式
每种IPC方式都有优缺点和适用场景。
- 关于Binder线程池
- Binder线程池
- android binder机制---ProcessState和线程池
- android的binder驱动 进程,线程,线程池
- android的binder驱动 进程,线程,线程池
- Binder线程处理请求
- Android Binder线程
- Android Binder线程
- Binder服务线程分析
- Binder通信过程中的用户空间线程池的管理
- Binder通信过程中的用户空间线程池的管理
- FregServer进程,启动Binder线程池,睡眠等待在proc->wait
- System、应用程序进程的Binder线程池和Handler消息循环
- Android应用程序启动Binder线程源码分析
- Android应用程序启动Binder线程源码分析
- IPC-Binder连接池
- Binder连接池
- Binder连接池
- 清华梦的粉碎—写给清华大学的退学申请 /王垠
- 洛谷 1387最大正方形
- Codeforces
- UVA 10791 最小公倍数的最小和
- 3.ARMv8 中断及异常处理(包括系统调用,系统调用即同步异常)
- Binder线程池
- 3.Spark-RDD原理
- zzuli 2179: 紧急营救
- 《leetcode》single-number-ii
- 逆序对
- 原码、反码、补码以及补码是怎么来的
- 最大的最大公约数
- SQL学习记录
- HDU-2087 剪花布条(KMP不重复字符串匹配次数统计)