“This is the sixth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
4. Client coding
The client needs to create a new project with the package name com.czy.client
First, you need to copy the server AIDL file and the Book class, and copy the entire AIDL folder to the same level as the Java folder without changing any code.
After that, you need to create the same package name as the Book class on the server
Modify the layout file by adding two buttons
<? The XML version = "1.0" encoding = "utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <Button android:id="@+id/btn_getBookList" android:layout_width="match_parent" android:layout_height="wrap_content" <Button android:id="@+id/btn_addBook_inOut" Android :layout_width="match_parent" Android :layout_height="wrap_content" Android :text="InOut add books "/> </LinearLayout>Copy the code
public class MainActivity extends AppCompatActivity { private final String TAG = "Client"; private BookController bookController; private boolean connected; private List<Book> bookList; private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { bookController = BookController.Stub.asInterface(service); connected = true; } @Override public void onServiceDisconnected(ComponentName name) { connected = false; }}; private View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_getBookList: if (connected) { try { bookList = bookController.getBookList(); } catch (RemoteException e) { e.printStackTrace(); } log(); } break; Case r.i.btn_addbook_inout: if (connected) {Book Book = new Book(" This is a new Book InOut"); try { bookController.addBookInOut(book); Log.e(TAG, "added a new book to the server InOut "); Log.e(TAG, "new title:" + book.getName()); } catch (RemoteException e) { e.printStackTrace(); } } break; }}}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_getBookList).setOnClickListener(clickListener); findViewById(R.id.btn_addBook_inOut).setOnClickListener(clickListener); bindService(); } @Override protected void onDestroy() { super.onDestroy(); if (connected) { unbindService(serviceConnection); } } private void bindService() { Intent intent = new Intent(); intent.setPackage("com.czy.server"); intent.setAction("com.czy.server.action"); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } private void log() { for (Book book : bookList) { Log.e(TAG, book.toString()); }}}Copy the code
Two buttons are used to get the list of books on the server and to add books.
When adding a Book, the server also changes the Name property of the Book object to see how the client and server data change:
First click to get the book list, the data is correct
Click the button to add the book, and you can see that the changes made by the server are synchronized to the client side
At this point, the communication between the client and the server is complete. The client gets the data from the server and sends the data to the server.
5. Directional Tag
Finally, I’ll talk about the differences between the three targeted tags.
Using the InOut type, changes made by the server are synchronized to the client, so data flows in both directions.
In: Data can only be transmitted from the client to the server. The modification of data by the server does not affect the client.
The representation of the Out type is that data can only be passed from the server to the client. Even if the client passes an object to the method interface, the attribute value in the object is empty, that is, it does not contain any data. After the server obtains the object, any operation on the object will be synchronized to the client.
So let’s do a real demonstration here
Start by modifying the bookController.aidl file on the server and adding two new methods to it
package com.czy.server;
import com.czy.server.Book;
interface BookController {
List<Book> getBookList(a);
void addBookInOut(inout Book book);
void addBookIn(in Book book);
void addBookOut(out Book book);
}
Copy the code
The bookController.stub object of the AIDLService class needs to be modified as follows:
private final BookController.Stub stub = new BookController.Stub() {
@Override
public List<Book> getBookList(a) throws RemoteException {
return bookList;
}
@Override
public void addBookInOut(Book book) throws RemoteException {
if(book ! =null) {
book.setName("The server changed the name of the new book to InOut");
bookList.add(book);
} else {
Log.e(TAG, "Received an empty object InOut"); }}@Override
public void addBookIn(Book book) throws RemoteException {
if(book ! =null) {
book.setName("The server changed the name of the new book to In");
bookList.add(book);
} else {
Log.e(TAG, "Received an empty object In"); }}@Override
public void addBookOut(Book book) throws RemoteException {
if(book ! =null) {
Log.e(TAG, "The name of the book from the client:" + book.getName());
book.setName("The server changed the name of the new book Out.");
bookList.add(book);
} else {
Log.e(TAG, "Received an empty object Out"); }}};Copy the code
Synchronize changes to the bookController.aidl file on the client
Add two more buttons to the layout file, each for adding different targeted Tag data
private View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_getBookList:
if (connected) {
try {
bookList = bookController.getBookList();
} catch (RemoteException e) {
e.printStackTrace();
}
log();
}
break;
case R.id.btn_addBook_inOut:
if (connected) {
Book book = new Book("This is a new book InOut.");
try {
bookController.addBookInOut(book);
Log.e(TAG, "InOut added a new book to the server");
Log.e(TAG, "New title:" + book.getName());
} catch(RemoteException e) { e.printStackTrace(); }}break;
case R.id.btn_addBook_in:
if (connected) {
Book book = new Book("This is a new book.");
try {
bookController.addBookIn(book);
Log.e(TAG, "Added a new book to the server In");
Log.e(TAG, "New title:" + book.getName());
} catch(RemoteException e) { e.printStackTrace(); }}break;
case R.id.btn_addBook_out:
if (connected) {
Book book = new Book("This is a new book Out.");
try {
bookController.addBookOut(book);
Log.e(TAG, "Added a new book to the server in Out mode");
Log.e(TAG, "New title:" + book.getName());
} catch(RemoteException e) { e.printStackTrace(); }}break; }}};Copy the code
In addition, there is one area that needs to be modified, namely the Book class. Because the Out type does cause the client to pass an object back to the server that contains no data, but that object is not null, the system still needs to instantiate the Book class. Currently, the Book class has only one argument constructor, so we need to modify the Book class. Add a no-parameter constructor for use by the system
Click the three buttons respectively, and you can see that the server does not contain the title property value when it gets the Book object from the client in Out mode
This is the end of AIDL.