An overview of the

AIDL can realize the communication between processes. Since each process runs in an independent space, different processes need to use some special ways to interact. AIDL is one of them, and AIDL is a template. AIDL is a template for avoiding repetitive code writing

grammar

The syntax of AIDL is very simple and basically the same as that of the Java language. Here are some rules to keep in mind:

  • AIDL files have an. AIDL file name extension. AIDL supports the following data types:

    • There are eight basic data types: byte, char, int, long, float, double, Boolean String, CharSequence. Short is not supported
    • Implements the data type of the Parcelable interface
    • The List type. The data carried by the List must be of a type supported by AIDL, or another declared AIDL object
    • The Map type. The data hosted by the Map must be of the type supported by AIDL or other declared AIDL objects
  • Orientation of the Tag. Directional Tag represents the flow direction of data in cross-process communication, and is used to mark the parameter values of methods, including in, OUT and InOUT. Among them

    • In indicates that data flows from the client to the server
    • Out indicates that data can only be transferred from the server to the client
    • Inout indicates that data can be bidirectional between the server and the client
    • In addition, if the parameter value type of the AIDL method interface is: For basic data types, String, CharSequence, or other method interfaces defined in AIDL files, the default Tag for these parameter values is in, so all parameter values except these types need to be clearly marked with which Tag to use. Specific differences in the use of directional tags will be described later
  • Clear guide package. You need to specify the package name of the referenced data type in an AIDL file, even if both files are under the same package name

The service side

  • Start with a project
  • Since you want to transfer custom User objects, define a User aiDL file, generated directly

    By default, the system creates an aidl folder with the name of the project package, book. aidi, and changes the contents of the user. aidl file

package com.baidu.bpit.aibaidu.aidl;

parcelable User;
Copy the code
  • Then generate a User class that implements Parcelable
public class User implements Parcelable {

    public String name;

    public User(String name){
        this.name=name;
    }

    protected User(Parcel in) {
        name = in.readString();
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            returnnew User[size]; }}; @Override public intdescribeContents() {
        return0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); }}Copy the code
  • And then define a BookName aidl file, exposed to the client can call interface, need to manually import the User, the import com. Baidu. Bpit. Aibaidu. Aidl. User;
package com.baidu.bpit.aibaidu.aidl;
import com.baidu.bpit.aibaidu.aidl.User;
interface BookName {
   String getName();

   List<User> getList();

 }
Copy the code
  • This is the time to rebuild the project
  • Now you need to create a Service that the client can bind to remotely, returning your custom Binder

public class ServiceService extends Service {
    public ServiceService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }

    class MyBinder extends BookName.Stub {

        @Override
        public String getName() throws RemoteException {
            return Journey to the West;
        }

        @Override
        public List<User> getList() throws RemoteException {
            User user = new User("111");
            User user1 = new User("222");
            List<User> users = new ArrayList<>();
            users.add(user1);
            users.add(user);
            returnusers; }}}Copy the code
  • Androidmanifest.xml file definition
 <service
            android:name=".ServiceService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.aaa.aaa" />
            </intent-filter>
    </service>
Copy the code

The client

  • First, copy the server aiDL folder to the client
  • After that, you need to create the same package name as the server User class to hold the User class
  • In the Service bound to the MainActivity server, click the button to get the title

public class MainActivity extends AppCompatActivity {

    private BookName bookName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindServer();
        initView();
    }

    private void initView() {
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Log.d("mmmgetName", bookName.getName());
                    List<User> list = bookName.getList();
                    for (User user : list) {
                        Log.d("mmmgetList", user.name); } } catch (RemoteException e) { e.printStackTrace(); }}}); } private voidbindServer() { Intent mIntent = new Intent(); // Action minten.setAction ("com.aaa.aaa"); // Here you need to set the package name of your application minten.setPackage ("com.baidu.bpit.aibaidu.aidl");
        bindService(mIntent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { bookName = BookName.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }, BIND_AUTO_CREATE); }}Copy the code
  • Click the button to print
01-18 22:11:17. 642, 4542-4542 / com. Baidu. Bpit. Aibaidu. Client/mmmgetName D: Journey to the west 01-18 22:11:17. 643, 4542-4542 / com. Baidu. Bpit. Aibaidu. Client D/mmmgetList: 222 111Copy the code

Get the data right

Directional TAG

There are three types of directional tags

  • Inout: When the server modifies data, the data is synchronized to the client. Therefore, data flows in both directions
  • In: Data flows only from the client to the server. The modification of data by the server does not affect the client
  • Out: Data can only be transmitted from the server to the client. Even if the client passes in an object, the object is empty, that is, without data. After the server obtains the object, any operation on the object will be synchronized to the client

Modify the aidl

interface BookName {
   String getName();

   List<User> getList();

   void addInout(inout User user);
   void addIn(in User user);
   void addout(out User user);
 }
Copy the code

I’m going to add three methods addInout, addIn, addout, and then I’m going to test them separately

The User class needs to add two methods, a no-argument construct and a readFromParcel

public class User implements Parcelable {

    public String name;

    public User(){

    }

    public User(String name){
        this.name=name;
    }

    protected User(Parcel in) {
        name = in.readString();
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            returnnew User[size]; }}; @Override public intdescribeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
    }
    public void readFromParcel(Parcel dest) { name = dest.readString(); }}Copy the code

Let’s test inout

The service side


public class ServiceService extends Service {
    public ServiceService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }

    class MyBinder extends BookName.Stub {

        @Override
        public String getName() throws RemoteException {
            return Journey to the West;
        }

        @Override
        public List<User> getList() throws RemoteException {
            User user = new User("111");
            User user1 = new User("222");
            List<User> users = new ArrayList<>();
            users.add(user1);
            users.add(user);
            return users;
        }

        @Override
        public void addInout(User user) throws RemoteException {
                Log.d("mmmserver"."Server gets:"+user.name);
                user.name="Server Changes";
                Log.d("mmmserver"."Server change title:"+user.name);
        }

        @Override
        public void addIn(User user) throws RemoteException {

        }

        @Override
        public void addout(User user) throws RemoteException {

        }
    }
}
Copy the code

It mainly depends on the inout method. After receiving the information from the client, the server modifies the information

The client

  private void initView() {
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    User user = new User("Client incoming");
                    Log.d("mmmclient"."The client passes a book to the server called:" + user.name);
                    bookName.addInout(user);
                    Log.d("mmmclient".After the server modifies the title, the title:+ user.name); } catch (RemoteException e) { e.printStackTrace(); }}}); }Copy the code

After the button is clicked, data is passed to the server. The server receives the data and changes the data. The client checks the data again to see whether it is synchronized

01-18 23:15:18. 529, 5606-5606 / com. Baidu. Bpit. Aibaidu. Client/mmmclient D: The client to the server into a book, the title: the client incoming 01-18 23:15:18. 529, 5527-5554 / com. Baidu. Bpit. Aibaidu. Aidl D/mmmserver: The server access to: the client incoming 01-18 23:15:18. 530, 5527-5554 / com. Baidu. Bpit. Aibaidu. Aidl D/mmmserver: Server to modify the title: the server change 01-18 23:15:18. 530, 5606-5606 / com. Baidu. Bpit. Aibaidu. Client D/mmmclient: server after modifying the title, the title: the server changesCopy the code

This is the two-way flow of inOUT data

The test in

The service side

  @Override
        public void addIn(User user) throws RemoteException {
                Log.d("mmmserverIn"."Server gets:" + user.name);
                user.name = "Server Changes";
                Log.d("mmmserverIn"."Server change title:" + user.name);
        }
Copy the code

The client

    private void initView() {
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    User user = new User("Client incoming");
                    Log.d("mmmclient"."The client passes a book to the server called:" + user.name);
                    bookName.addIn(user);
                    Log.d("mmmclient".After the server modifies the title, the title:+ user.name); } catch (RemoteException e) { e.printStackTrace(); }}}); }Copy the code

When the button is clicked, data is sent to the server, which changes the data content, and the client looks at the data again to see if it has been changed

01-18 23:26:23. 079, 5815-5815 / com. Baidu. Bpit. Aibaidu. Client/mmmclient D: The client to the server into a book, the title: the client incoming 01-18 23:26:23. 080, 5736-5763 / com. Baidu. Bpit. Aibaidu. Aidl D/mmmserverIn: The server access to: the client incoming 01-18 23:26:23. 081, 5736-5763 / com. Baidu. Bpit. Aibaidu. Aidl D/mmmserverIn: Server to modify the title: the server change 01-18 23:26:23. 081, 5815-5815 / com. Baidu. Bpit. Aibaidu. Client D/mmmclient: server after modifying the title, the title: the client incomingCopy the code

See if the server modifies the data without affecting the client

Test OUT

The service side

  @Override
        public void addout(User user) throws RemoteException {
            Log.d("mmmserverout"."Server gets:" + user.name);
            user.name = "Server Changes";
            Log.d("mmmserverout"."Server change title:" + user.name);
        }
Copy the code

The client


    private void initView() {
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    User user = new User("Client incoming");
                    Log.d("mmmclient"."The client passes a book to the server called:" + user.name);
                    bookName.addout(user);
                    Log.d("mmmclient".After the server modifies the title, the title:+ user.name); } catch (RemoteException e) { e.printStackTrace(); }}}); }Copy the code

The client passes data to the server, the server receives it, changes the data, and the client reviews the data again

01-18 23:36:21. 997, 6100-6100 / com. Baidu. Bpit. Aibaidu. Client/mmmclient D: The client to the server into a book, the title: the client incoming 01-18 23:36:21. 998, 6023-6037 / com. Baidu. Bpit. Aibaidu. Aidl D/mmmserverout: Server access to: null server to modify the title: the server change 01-18 23:36:21. 998, 6100-6100 / com. Baidu. Bpit. Aibaidu. Client D/mmmclient: server after modifying the title, the title: the server changesCopy the code

You can see that the server receives an empty object, and the server changes affect the client

Making: reference: www.jianshu.com/p/29999c1a9…