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…