Processing of multiple AIDL files connected by a Binder connection pool

Posted by coder4Ever on Sat, 13 Jul 2019 18:19:49 +0200

Processing of multiple AIDL files connected by a Binder connection pool


Note beforehand:

I am also a beginner, so this article starts from a beginner's point of view, if there are inappropriate places, please leave a message to teach me, thank you.

If you don't understand the use of AIDL and the Binder mechanism, you can refer to my previous articles. Android Foundation - The Binder Mechanism of AIDL on Application Layer for Beginnershttp://blog.csdn.net/qq_30379689/article/details/52253413


Preface:

According to our previous use of AIDL, one AIDL interface must be satisfied for one service.If our application requires more than one AIDL for more than one module, then more than one Service end is needed. Service is the four components with a high memory footprint, which affects the performance of the application.So we need to put all the AIDLs into one service to manage them.

Welcome to my CSDN blog, Hensen_blog, http://blog.csdn.net/qq_30379689


How Binder Connection Pooling works:



Service-side operations

Step 1: Create the aidl file needed by the two modules and create a Binder connection pool aidl file to compile Gradle


  1. interface IMyAidlInterface {  
  2.     int add(int num1,int num2);  
  3. }  

  1. interface IMyAidl2Interface {  
  2.      String print_A();  
  3.      String print_B();  
  4. }  
  1. interface IMyBinderPoolInterface {  
  2.      IBinder queryBinder(int binderCode);  
  3. }  
Step 2: Create two modules to implement the aidl file class and create a Binder connection pool class and implement, create a server

  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. }  
  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. }  
  1. public class BinderPool {  
  2.     //Gets the identity of the AIDL proxy object  
  3.     private static final int BINDER_1 = 0;  
  4.     private static final int BINDER_2 = 1;  
  5.   
  6.     /** 
  7.      * Methods to Implement AIDL Interface 
  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. }  
  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. }  
Step 3: Configure Service in manifests

  1. <service  
  2.             android:name=".Aidl.MyService"  
  3.             android:exported="true" />  
Step 4: Start the service in code

  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. }  


Client Operations
Step 1: Copy the server-side aidl file to the client and compile Gradle


Step 2: Write the code for the Binder connection pool and explain it in the code

  1. public class BinderPool {  
  2.   
  3.     //context  
  4.     private Context mContext;  
  5.     //Synchronization Auxiliary Class  
  6.     private CountDownLatch mCountDownLatch;  
  7.     //Singleton  
  8.     private static BinderPool mInstance;  
  9.     //Gets the identity of the AIDL proxy object  
  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.         //Get Context  
  17.         mContext = context.getApplicationContext();  
  18.         //Connect to remote services  
  19.         connectBinderPoolService();  
  20.     }  
  21.   
  22.     /** 
  23.      * Singleton mode 
  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.      * Provides a query method for this class 
  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.      * Open remote services and keep them in sync 
  59.      */  
  60.     private synchronized void connectBinderPoolService() {  
  61.         //Synchronization assistant, value 1  
  62.         mCountDownLatch = new CountDownLatch(1);  
  63.         //Open Remote Service  
  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.             //Synchronization assistant  
  69.             mCountDownLatch.await();  
  70.         } catch (InterruptedException e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.     }  
  74.   
  75.     /** 
  76.      * Connect Server Interface 
  77.      */  
  78.     private ServiceConnection conn = new ServiceConnection() {  
  79.         @Override  
  80.         public void onServiceConnected(ComponentName name, IBinder service) {  
  81.             mBinderPoolInterface = IMyBinderPoolInterface.Stub.asInterface(service);  
  82.             //Bind death monitoring  
  83.             try {  
  84.                 mBinderPoolInterface.asBinder().linkToDeath(mDeathRecipient, 0);  
  85.             } catch (RemoteException e) {  
  86.                 e.printStackTrace();  
  87.             }  
  88.             //Synchronization assistant, value minus 1  
  89.             mCountDownLatch.countDown();  
  90.         }  
  91.   
  92.         @Override  
  93.         public void onServiceDisconnected(ComponentName name) {  
  94.   
  95.         }  
  96.     };  
  97.   
  98.     /** 
  99.      * The death monitoring interface, which is returned if the Binder object suddenly stops servicing during use 
  100.      */  
  101.     private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {  
  102.         @Override  
  103.         public void binderDied() {  
  104.             //Cancel death monitoring  
  105.             mBinderPoolInterface.asBinder().unlinkToDeath(mDeathRecipient, 0);  
  106.             //Release Resources  
  107.             mBinderPoolInterface = null;  
  108.             //Reconnect service  
  109.             connectBinderPoolService();  
  110.         }  
  111.     };  
  112.   
  113. }  
Step 3: Use in code

  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.                 //If no child threads are used here, ANR errors will result because the server connection is a time-consuming task  
  11.                 startBinderPool();  
  12.             }  
  13.         }).start();  
  14.     }  
  15.   
  16.     private void startBinderPool() {  
  17.         BinderPool binderPool = BinderPool.getInstance(this);  
  18.         //First module  
  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 Results:" + str1);  
  25.             Log.i("------""Aidl2 Results:" + str2);  
  26.         } catch (RemoteException e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.         //Second module  
  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 Calculation results:" + res);  
  35.         } catch (RemoteException e) {  
  36.             e.printStackTrace();  
  37.         }  
  38.     }  
  39. }  
Step 4: Start the server, then start the client, view the Log, test results
  1. 08-25 00:13:04.025 3538-3566/com.handsome.app2 I/-----------: Aidl2 results: A
  2. 08-25 00:13:04.025 3538-3566/com.handsome.app2 I/-----------: Aidl2 Result: B
  3. 08-25 00:13:04.028 3538-3566/com.handsome.app2 I/-----------: Aidl1 results: 4

Topics: Android Gradle