preface

In this paper, the interprocess communication between two APPS is realized by Binder connection pool. Advantages of Binder connection pools: The server provides a queryBinder interface that returns Binder objects to the business module based on its unique identifier. Different business modules can use the required Binder objects to call remote methods. There is no need to create a Service on the server side for a single module, otherwise a single module would have to create ten services on the server side to call them.

Implementation:

First, write to the server.

1. Create a new project in Android Studio, switch to the Project structure, right-click main, new – >Folder – >AIDLFolder, and create a new AIDLFolder as shown below

2, right-click the AIDL folder new – > Package and create a Package name for the AIDL interface

3. Create three AIDL interface files required by the server

3.1 IbInderPool. aidl Interfaces are Binder connection pools

// IBinderPool.aidl package com.ang; // Declare any non-default types here with import statements interface IBinderPool { /** * Demonstrates some basic types  that you can use as parameters * and return values in AIDL. */ IBinder queryBinder(int binderCode); }Copy the code

3.2 The ICompute. Aidl interface realizes the function of calculating addition

// ICompute.aidl
package com.ang;

// Declare any non-default types here with import statements

interface ICompute {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    int add(int a,int b);
}
Copy the code

3.3 ISecurityCenter. Aidl Interface Implements encryption and decryption

// ISecurityCenter.aidl
package com.ang;

// Declare any non-default types here with import statements

interface ISecurityCenter {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */

    String encrypt(String content);
    String decrypt(String password);
}
Copy the code

4, compile, in the following directory will automatically generate three AIDL interface corresponding Java interface

4, implement the above three automatically generated Java interfaces under the Java package, note the difference between the two package names

4.1 Create BinderPoolService under app package name and implement ibinderPool. Java interface;

Android: Exported =”true”;

package com.ang.binderpoolservice; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.widget.Toast; import com.ang.IBinderPool; public class BinderPoolService extends Service { private static final String TAG = "BinderPoolService"; public static final int BINDER_COMPUTE = 0; public static final int BINDER_SECURITY_CENTER = 1; private Binder mBinderPool = new IBinderPool.Stub() { @Override public IBinder queryBinder(int binderCode) throws RemoteException { IBinder binder = null; switch (binderCode) { case BINDER_SECURITY_CENTER: binder = new SecurityCenterImpl(); break; case BINDER_COMPUTE: binder = new ComputeImpl(); break; } return binder; }}; public BinderPoolService() { } @Override public IBinder onBind(Intent intent) { return mBinderPool; } @override public void onCreate() {log.d (TAG, "onCreate started "); Toast.maketext (this,"onCreate started ", toast.length_long).show(); super.onCreate(); }}Copy the code

4.2 Implement the other two AIDL interfaces corresponding to the generated Java interfaces

package com.ang.binderpoolservice; import android.os.RemoteException; import com.ang.ICompute; /** * @param a * @param b * @return */ public class ComputeImpl extends ICompute.Stub { @Override public int add(int a, int b) throws RemoteException { return a + b; }}Copy the code
package com.ang.binderpoolservice; import android.os.RemoteException; import com.ang.ISecurityCenter; /** * @param a * @param b * @return */ 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); }}Copy the code

Second, client implementation

1. Create a new project as you did in the previous two steps on the server side, and then create an AIDL folder

2. Copy the package name and aiDL file from the aiDL folder on the server side to this folder. That is, the package name and path must be the same as the AIDL interface on the server side.

3, compile, the result is the same as the server, automatically generated and aiDL interface corresponding to the Java interface;

4. Bind bindService to BinderPoolService on the MainActivity client; Once the binding is successful, remote server methods can be invoked;

package com.ang.binderpoolclient; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.ang.IBinderPool; import com.ang.ICompute; import java.util.concurrent.CountDownLatch; public class MainActivity extends AppCompatActivity { private String TAG = "BinderPoolClientActivity"; public static final int BINDER_COMPUTE = 0; public static final int BINDER_SECURITY_CENTER = 1; private CountDownLatch countDownLatch; private Button btn_bind_service; private IBinderPool binderPool; private IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() { @Override public void binderDied() { binderPool.asBinder().unlinkToDeath(deathRecipient, 0); binderPool = null; connectBinderPoolService(); }}; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName  name, IBinder service) { binderPool = IBinderPool.Stub.asInterface(service); Toast.maketext (mainactivity.this, "bind successfully ", toast.length_long).show(); try { IBinder binder = binderPool.queryBinder(BINDER_COMPUTE); ICompute iCompute = ICompute.Stub.asInterface(binder); // icompute.add (2, 5) invokes the remote server method toast.maketext (mainactivity.this, "" + icompute.add (2, 5), toast.length_long).show(); } catch (RemoteException e) { e.printStackTrace(); } try { binderPool.asBinder().linkToDeath(deathRecipient, 0); } catch (RemoteException e) { e.printStackTrace(); } countDownLatch.countDown(); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_bind_service = findViewById(R.id.btn_bind_service); btn_bind_service.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { connectBinderPoolService(); }}); } private synchronized void connectBinderPoolService() { countDownLatch = new CountDownLatch(1); Intent intent = new Intent(Intent.ACTION_VIEW); String packageName = "com.ang.binderpoolservice"; String className = "com.ang.binderpoolservice.BinderPoolService"; intent.setClassName(packageName, className); bindService(intent, mConnection, MainActivity.BIND_AUTO_CREATE); Toast.maketext (mainactivity.this, "Start remote service ", toast.length_long).show(); } @Override protected void onDestroy() { super.onDestroy(); unbindService(mConnection); }}Copy the code

Note:

BindService is an asynchronous operation;

 

Download the source code