android 跨应用进程之间的通信之AIDL
2018-01-24 18:00
260 查看
通常我们熟悉同一进程的通信方式,关于跨进程之间的通信AIDL的实现方式。
Android studio提供了aldl工具,创建步骤
1、右击项目文件,选择AIDL File
2、我们可以任意取一个文件名,点击finish
3、创建接口文件
4、创建我们要获取对象数据的Book.java文件
下面分别把这三个文件的源代码贴出来:
Book.java
Book.aidl文件
IBookManager.aidl文件
我们点击编辑,在app/build/generated/source/debug/目录下会自动生成一个IBookManager.java文件
下面已service和client分别作为不同进程为例,做具体的实现过程。service和client可以是同一个android应用,也可以是不同的两个android应用。以上的三个文件作为两个进程通讯的基础文件。
Service端代码
client的读取service数据对象的代码:
首先绑定服务端
然后获取服务端进程数据对象
当然我们定义serviceconnection对象
即可完成跨进程之间的通信。
这里关于aidl文件的生成还有一种方式。可以写IBookManager.java文件,用法类似。
IBookManager.java文件代码通自动生成编译代码一样。
编译运行过程中出现以下报错信息:
Binder invocation to an incorrect interface
错误解决:确保service和client两进程的IBookManager.java文件中的以下变量值保持一致。如果是自动生成模式可以,修改aidl包名一致,如果是手动创建的IBookManager.java文件可以直接修改一致的变量值。即可解决上述报错问题。
代码下载地址如下所示:
服务端源代码下载地址
客户端源代码下载地址
Android studio提供了aldl工具,创建步骤
1、右击项目文件,选择AIDL File
2、我们可以任意取一个文件名,点击finish
3、创建接口文件
4、创建我们要获取对象数据的Book.java文件
下面分别把这三个文件的源代码贴出来:
Book.java
public class Book implements Parcelable { private String bookName; private String bookPrice; protected Book(Parcel in) { bookName = in.readString(); bookPrice = in.readString(); } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getBookPrice() { return bookPrice; } public void setBookPrice(String bookPrice) { this.bookPrice = bookPrice; } public static final Creator<Book> CREATOR = new Creator<Book>() { @Override public Book createFromParcel(Parcel in) { return new Book(in); } @Override public Book[] newArray(int size) { return new Book[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(bookName); dest.writeString(bookPrice); } }
Book.aidl文件
package package com.test.Book.aidl; // Declare any non-default types here with import statements parcelable Book;
IBookManager.aidl文件
package com.test.Book.aidl; // Declare any non-default types here with import statements import com.test.Book; interface IBookManager { List<Book> getBookList(); void addBook(in Book book); }
我们点击编辑,在app/build/generated/source/debug/目录下会自动生成一个IBookManager.java文件
下面已service和client分别作为不同进程为例,做具体的实现过程。service和client可以是同一个android应用,也可以是不同的两个android应用。以上的三个文件作为两个进程通讯的基础文件。
Service端代码
public class BindService extends Service { List<Book> books = new ArrayList<>(); private final IBookManager.Stub binder = new IBookManager.Stub() { @Override public List<Book> getBookList() throws RemoteException { synchronized (books) { return books; } } @Override public void addBook(Book book) throws RemoteException { synchronized (book) { if (!books.contains(book)) { books.add(book); } } } }; @Override public void onCreate() { super.onCreate(); Book book = new Book("图书一","10"); books.add(book); } @Nullable @Override public IBinder onBind(Intent intent) { Book book = new Book("图书二","20"); if (books == null) { books.add(book); }else { if (!books.contains(book)) { books.add(book); } } return binder; } }
client的读取service数据对象的代码:
首先绑定服务端
public void onBindService() { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.test.test", "com.test.tes.BindService")); bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE); }
然后获取服务端进程数据对象
public void getBookList(View view) { try { List<Book> bookList = binders.getBookList(); for(Book book:bookList) { Log.e(tag,book.toString()); } }catch (Exception e) { Log.e(tag,e.getMessage()); } }
当然我们定义serviceconnection对象
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { binders = IBookManager.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } };
即可完成跨进程之间的通信。
这里关于aidl文件的生成还有一种方式。可以写IBookManager.java文件,用法类似。
IBookManager.java文件代码通自动生成编译代码一样。
public static abstract class Stub extends android.os.Binder implements IBookManager { private static final String DESCRIPTOR = "com.test.IBookManager"; /** * Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } public static IBookManager asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof IBookManager))) { return ((IBookManager) iin); } return new Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getBookList: { data.enforceInterface(DESCRIPTOR); java.util.List<Book> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); Book _arg0; if ((0 != data.readInt())) { _arg0 = Book.CREATOR.createFromParcel(data); } else { _arg0 = null; } this.addBook(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements IBookManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public String getInterfaceDescriptor() { return DESCRIPTOR; } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */// void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, // double aDouble, String aString); @Override public java.util.List<Book> getBookList() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.util.List<Book> _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArrayList(Book.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void addBook(Book book) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((book != null)) { _data.writeInt(1); book.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */// void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, // double aDouble, String aString); public java.util.List<Book> getBookList() throws android.os.RemoteException; public void addBook(Book book) throws android.os.RemoteException; }
编译运行过程中出现以下报错信息:
Binder invocation to an incorrect interface
错误解决:确保service和client两进程的IBookManager.java文件中的以下变量值保持一致。如果是自动生成模式可以,修改aidl包名一致,如果是手动创建的IBookManager.java文件可以直接修改一致的变量值。即可解决上述报错问题。
private static final String DESCRIPTOR = "com.test.IBookManager";
代码下载地址如下所示:
服务端源代码下载地址
客户端源代码下载地址
相关文章推荐
- 一篇文章读懂Android组件之间数据传递方法 IPC进程通信方法AIDL介绍
- Android AIDL 进程之间的通信
- Android进程之间通信Aidl
- Android AIDL 实现两个APP之间的跨进程通信实例
- AIDL跨进程通信在Android的应用
- Android 使用AIDL实现进程之间的通信(一)
- Android:AIDL进程之间的通信
- Android之AIDL进程之间的通信
- Android的跨进程通信介绍----------------aidl,传递复杂对象以及Server和Clicent之间的回调
- aidl进程之间的通信
- 应用管道实现父子进程之间的通信
- Android 使用AIDL实现进程间的通信
- Android系统分析之AIDL跨进程通信机制的使用和原理分析
- android aidl进程间的通信
- AIDL实现Android的进程通信
- Android跨进程通信_aidl使用
- AIDL 的理解与使用(一种android内部进程通信接口的描述语言)
- Android学习路径(23)应用Fragment建立动态UI——Fragment之间的通信
- Android 两个进程之间使用AIDL
- Android 跨进程通信之:AIDL