zoukankan      html  css  js  c++  java
  • Binder连接池连接多个AIDL文件的处理

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


    事先说明:

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

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


    前言:

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

    欢迎关注我的CSDN博客,Hensen_的博客,http://blog.csdn.net/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  
  • 相关阅读:
    SQL Server 2005 镜像构建说明(转载)
    表变量 vs. 临时表
    SQL Server日志
    MDX常见计算方法(百分比/分配/平均值/基于时间的计算)
    MDX中一些边界问题的处理
    MDX中的Where vs. Subselect/Subcube
    MDX优化Set操作
    SSIS处理导入数据时, 存在的更新, 不存在的插入(转载)
    MDX实现同比和环比
    iPhone4S出现应用无法打开时的解决方案
  • 原文地址:https://www.cnblogs.com/vegetate/p/9997239.html
Copyright © 2011-2022 走看看