Binder连接池连接多个AIDL文件的处理

本文介绍如何通过Binder连接池管理多个AIDL接口,提高应用程序性能。包括服务端与客户端的实现步骤,以及如何避免ANR错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Binder连接池连接多个AIDL文件的处理


事先说明:

本人也是个初学者,所以本文是从初学者的角度入手,如果有不妥的地方请留言教导我,谢谢。

如果对AIDL的使用和Binder机制不懂的,可以参照我之前的文章,Android基础——初学者必知的AIDL在应用层上的Binder机制http://blog.youkuaiyun.com/qq_30379689/article/details/52253413


前言:

按照我们之前的对AIDL的使用方法,必须满足一个AIDL接口对应一个service。假如我们的应用,有多个模块需要多个AIDL,则需要多个Service端,Service作为四大组件,内存占用高,这样就影响了应用程序的性能了。所以我们需要将所有的AIDL放入一个Service中去管理。

欢迎关注我的优快云博客,Hensen_的博客,http://blog.youkuaiyun.com/qq_30379689


Binder连接池工作原理:



服务端的操作

步骤一:创建两个模块需要的aidl文件和创建一个Binder连接池aidl文件,编译一下Gradle


[java]  view plain  copy
  1. interface IMyAidlInterface {  
  2.     int add(int num1,int num2);  
  3. }  

[java]  view plain  copy
  1. interface IMyAidl2Interface {  
  2.      String print_A();  
  3.      String print_B();  
  4. }  
[java]  view plain  copy
  1. interface IMyBinderPoolInterface {  
  2.      IBinder queryBinder(int binderCode);  
  3. }  
步骤二:创建两个模块对aidl文件的实现类和创建一个Binder连接池类并实现,创建一个服务端

[java]  view plain  copy
  1. public class IMyAidlImpl extends IMyAidlInterface.Stub {  
  2.     @Override  
  3.     public int add(int num1, int num2) throws RemoteException {  
  4.         return num1 + num2;  
  5.     }  
  6. }  
[java]  view plain  copy
  1. public class IMyAidl2Impl extends IMyAidl2Interface.Stub {  
  2.     @Override  
  3.     public String print_A() throws RemoteException {  
  4.         return "A";  
  5.     }  
  6.   
  7.     @Override  
  8.     public String print_B() throws RemoteException {  
  9.         return "B";  
  10.     }  
  11. }  
[java]  view plain  copy
  1. public class BinderPool {  
  2.     //获取AIDL代理对象的标识  
  3.     private static final int BINDER_1 = 0;  
  4.     private static final int BINDER_2 = 1;  
  5.   
  6.     /** 
  7.      * 实现AIDL接口的方法 
  8.      */  
  9.     public static class IMyBinderPoolImpl extends IMyBinderPoolInterface.Stub {  
  10.   
  11.         @Override  
  12.         public IBinder queryBinder(int binderCode) throws RemoteException {  
  13.             IBinder binder = null;  
  14.             switch (binderCode) {  
  15.                 case BINDER_1:  
  16.                     binder = new IMyAidlImpl();  
  17.                     break;  
  18.                 case BINDER_2:  
  19.                     binder = new IMyAidl2Impl();  
  20.                     break;  
  21.                 default:  
  22.                     break;  
  23.             }  
  24.             return binder;  
  25.         }  
  26.     }  
  27. }  
[java]  view plain  copy
  1. public class MyService extends Service {  
  2.   
  3.     private Binder myBinder  = new BinderPool.IMyBinderPoolImpl();  
  4.   
  5.     @Override  
  6.     public IBinder onBind(Intent intent) {  
  7.         return myBinder;  
  8.     }  
  9.   
  10.     @Override  
  11.     public void onCreate() {  
  12.         super.onCreate();  
  13.     }  
  14.   
  15.     @Override  
  16.     public void onDestroy() {  
  17.         super.onDestroy();  
  18.     }  
  19. }  
步骤三:在manifests中配置Service

[java]  view plain  copy
  1. <service  
  2.             android:name=".Aidl.MyService"  
  3.             android:exported="true" />  
步骤四:在代码中启动服务

[java]  view plain  copy
  1. public class LoginActivity extends AppCompatActivity {  
  2.     @Override  
  3.     protected void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.activity_login);  
  6.   
  7.         startService(new Intent(this, MyService.class));  
  8.     }  
  9. }  


客户端的操作
步骤一:复制服务端的aidl文件到客户端中,编译一下Gradle


步骤二:编写Binder连接池的代码,解释在代码中

[java]  view plain  copy
  1. public class BinderPool {  
  2.   
  3.     //上下文  
  4.     private Context mContext;  
  5.     //同步辅助类  
  6.     private CountDownLatch mCountDownLatch;  
  7.     //单例  
  8.     private static BinderPool mInstance;  
  9.     //获取AIDL代理对象的标识  
  10.     public static final int BINDER_1 = 0;  
  11.     public static final int BINDER_2 = 1;  
  12.   
  13.     private IMyBinderPoolInterface mBinderPoolInterface;  
  14.   
  15.     private BinderPool(Context context) {  
  16.         //获取上下文  
  17.         mContext = context.getApplicationContext();  
  18.         //连接远程服务  
  19.         connectBinderPoolService();  
  20.     }  
  21.   
  22.     /** 
  23.      * 单例模式 
  24.      * 
  25.      * @param context 
  26.      * @return 
  27.      */  
  28.     public static BinderPool getInstance(Context context) {  
  29.         if (mInstance == null) {  
  30.             synchronized (BinderPool.class) {  
  31.                 if (mInstance == null) {  
  32.                     mInstance = new BinderPool(context);  
  33.                 }  
  34.             }  
  35.         }  
  36.         return mInstance;  
  37.     }  
  38.   
  39.     /** 
  40.      * 提供该类的一个查询方法 
  41.      * 
  42.      * @param binderCode 
  43.      * @return 
  44.      */  
  45.     public IBinder queryBinder(int binderCode) {  
  46.         IBinder binder = null;  
  47.         try {  
  48.             if (mBinderPoolInterface != null) {  
  49.                 binder = mBinderPoolInterface.queryBinder(binderCode);  
  50.             }  
  51.         } catch (RemoteException e) {  
  52.             e.printStackTrace();  
  53.         }  
  54.         return binder;  
  55.     }  
  56.   
  57.     /** 
  58.      * 开启远程服务,并保持同步 
  59.      */  
  60.     private synchronized void connectBinderPoolService() {  
  61.         //同步辅助器,值为1  
  62.         mCountDownLatch = new CountDownLatch(1);  
  63.         //开启远程服务  
  64.         Intent intent = new Intent();  
  65.         intent.setComponent(new ComponentName("com.handsome.boke""com.handsome.boke.Aidl.MyService"));  
  66.         mContext.bindService(intent, conn, mContext.BIND_AUTO_CREATE);  
  67.         try {  
  68.             //同步辅助器  
  69.             mCountDownLatch.await();  
  70.         } catch (InterruptedException e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.     }  
  74.   
  75.     /** 
  76.      * 连接服务器接口 
  77.      */  
  78.     private ServiceConnection conn = new ServiceConnection() {  
  79.         @Override  
  80.         public void onServiceConnected(ComponentName name, IBinder service) {  
  81.             mBinderPoolInterface = IMyBinderPoolInterface.Stub.asInterface(service);  
  82.             //绑定死亡监听  
  83.             try {  
  84.                 mBinderPoolInterface.asBinder().linkToDeath(mDeathRecipient, 0);  
  85.             } catch (RemoteException e) {  
  86.                 e.printStackTrace();  
  87.             }  
  88.             //同步辅助器,值减1  
  89.             mCountDownLatch.countDown();  
  90.         }  
  91.   
  92.         @Override  
  93.         public void onServiceDisconnected(ComponentName name) {  
  94.   
  95.         }  
  96.     };  
  97.   
  98.     /** 
  99.      * 死亡监听接口,如果Binder对象在使用过程中突然停止服务,就会返回这个接口 
  100.      */  
  101.     private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {  
  102.         @Override  
  103.         public void binderDied() {  
  104.             //取消死亡监听  
  105.             mBinderPoolInterface.asBinder().unlinkToDeath(mDeathRecipient, 0);  
  106.             //释放资源  
  107.             mBinderPoolInterface = null;  
  108.             //重新连接服务  
  109.             connectBinderPoolService();  
  110.         }  
  111.     };  
  112.   
  113. }  
步骤三:代码中使用

[java]  view plain  copy
  1. public class MainActivity extends AppCompatActivity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.         new Thread(new Runnable() {  
  8.             @Override  
  9.             public void run() {  
  10.                 //如果这里不用子线程,会导致ANR错误,因为服务器的连接是个耗时的任务  
  11.                 startBinderPool();  
  12.             }  
  13.         }).start();  
  14.     }  
  15.   
  16.     private void startBinderPool() {  
  17.         BinderPool binderPool = BinderPool.getInstance(this);  
  18.         //第一个模块  
  19.         IBinder binder2 = binderPool.queryBinder(BinderPool.BINDER_2);  
  20.         IMyAidl2Interface myAidl2Interface = IMyAidl2Interface.Stub.asInterface(binder2);  
  21.         try {  
  22.             String str1 = myAidl2Interface.print_A();  
  23.             String str2 = myAidl2Interface.print_B();  
  24.             Log.i("————————————""Aidl2的结果:" + str1);  
  25.             Log.i("————————————""Aidl2的结果:" + str2);  
  26.         } catch (RemoteException e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.         //第二个模块  
  30.         IBinder binder = binderPool.queryBinder(BinderPool.BINDER_1);  
  31.         IMyAidlInterface myAidlInterface = IMyAidlInterface.Stub.asInterface(binder);  
  32.         try {  
  33.             int res = myAidlInterface.add(13);  
  34.             Log.i("————————————""Aidl1的计算结果:" + res);  
  35.         } catch (RemoteException e) {  
  36.             e.printStackTrace();  
  37.         }  
  38.     }  
  39. }  
步骤四:启动服务端,然后启动客户端,查看Log,测试结果
[java]  view plain  copy
  1. 08-25 00:13:04.025 3538-3566/com.handsome.app2 I/————————————: Aidl2的结果:A  
  2. 08-25 00:13:04.025 3538-3566/com.handsome.app2 I/————————————: Aidl2的结果:B  
  3. 08-25 00:13:04.028 3538-3566/com.handsome.app2 I/————————————: Aidl1的计算结果:4  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值