使用AIDL进行跨进程通信
AIDL是Android Interface definition language的缩写,是一种Android内部进程通信接口描述语言,通过AIDL可以定义进程间的通信接口。
AIDL支持的数据类型:
基本数据类型(int,long,char,boolean,double等);
String和CharSequence;
List:只支持ArrayList,里面每个元素都必须能够被AIDL支持;
Map:只支持HashMap,里面的每个元素都必须被AIDL支持,包括key和value;
Parcelable:所有实现了Parcelable接口的对象,
自定义的Parcelable对象和AIDL对象无论它们是否和当前的AIDL文件位于同一个馆内,都必须要显式import进来;
AIDL:所有的AIDL接口本身也可以在AIDL文件中使用。
首先分析下使用AIDL来进行进程间通信的流程,包括服务端和客户端两个方面:
1.服务端
服务端首先要创建一个Service用来监听客户端的连接请求,然后创建一个AIDL文件,将显露给客户端的接口在这个AIDL文件中声明,最后在Service中实现这个AIDL接口即可。
//BookMangerService.java文件, 注意模拟时,可以在Manifest文件中定义为单独一个服务器端进程来实现.
//BookMangerService.java文件, 注意模拟时,可以在Manifest文件中定义为单独一个服务器端进程来实现.
public class BookManagerService extends Service {
private static final String TAG = "BookManagerService";
private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<Book>(); //接口实现,创建Binder对象.继承自IBookManager.Stub
private Binder mBinder = new IBookManager.Stub() { @Override public List<Book> getBookList() throws RemoteException {
return mBookList;
} @Override public void addBook(Book book) throws RemoteException {
mBookList.add(book);
} }
}
2.创建AIDL接口
<span style="font-family: 微软雅黑; font-size: 14px; line-height: 21px;">//Book.aidl文件,为在传输过程中涉及的</span>
package com.dragon.aidl;
parcelable Book;
//IBookManager.aidl文件
package com.dragon.aidl;
import com.dragon.aidl.Book; interface IBookManager{
List<Book> getBookList();
void addBook(in Book book);
}
3.客户端
首先需要绑定服务端的Service,绑定成功后,奖服务端返回的Binder对象转换成AIDL接口所属的类型,接着可以调用AIDL中的方法。
public class BookManagerActivity extends BaseActivity {
private ServiceConnection mConnection = new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) {
//2.绑定成功后,将服务端返回的Binder对象转换成AIDL接口,然后可以通过这个接口去调用服务端的远程方法。
IBookManager bookManager = IBookManager.Stub.asInterface(service);
try{ List<Book> list = bookManager.getBookList();
//3.测试addBook方法
Book book = new Book(3, "AIDL测试..");
bookManager.addBook(book);
List<Book> newList = bookManager.getBookList();
Log.i(TAG, "query book list, newList type:" + newList.getClass().getCanonicalName());
Log.i(TAG, "query book newList:" + newList.toString()); //添加监听}catch (RemoteException e){ e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; }
1.如果在AIDL文件中用到了自定义的Parcelable对象,那么必须新建一个和它同名的AIDL文件,并在其中声明它为Parceable类型。
2.AIDL中除了基本数据类型,其它数据类型的参数必须标上方向:in, out 或者inout, in表示输入型参数,out表示输出型参数,inout表示输入输出参数。
3.AIDL接口中只支持方法,不支持声明静态常量,这一点区别于传统的接口。