Android中的IPC方式(二)—— AIDL
2016-06-08 23:38
281 查看
上一篇介绍了用Messenger来进行进程间通信的方法,可以发现,Messenger是以串行的方式处理客户端发来的信息的,如果有大量消息同时发到服务端,服务端只能一个一个处理,如果有大量信息的并发请求,那么用Messenger就不太合适了。Messenger主要作用只是传递消息,无法做到跨进程调用服务端的方法,这时就需要 AIDL 来实现跨进程调用服务端的方法。
服务端首先要创建一个 Service 用来监听客户端的连接请求,然后创建一个 AIDL 文件,将暴露给客户端的接口在这个 AIDL 文件中声明,最后在 Service 中实现这个 AIDL 接口即可。
2 . 客户端
客户端首先要绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转换成 AIDL 接口所属的类型,就可以调用 AIDL 中的方法了。
3 . AIDL 接口的创建
创建一个 .aidl 文件,声明一个接口和一些方法,如:
AIDL 支持的数据类型
基本数据类型(int、long、char等 )
String 和 CharSequence
List:只支持ArrayList,里面的每个元素必须被 AIDL 支持
Map:只支持HashMap ,里面的每个元素都必须被 AIDL 支持,包括 key 和 value
Parcelable:所有实现了Parcelable接口的对象
AIDL:所有的 AIDL 接口本身也可以在 AIDL 文件中使用
注意:如果需要用到自定义的Parcelable对象,必须要新建一个同名的 AIDL 文件,并在其中声明它为Parcelable类型,例如:
4 . 远程服务端Service的实现
5 . 客户端的实现
log日志
稍作修改,现在客户端给服务端添加一本书,然后再获取一次。
log日志
AIDL 进行进程间通信的流程,分为服务端和客户端两个方面:
1 . 服务端服务端首先要创建一个 Service 用来监听客户端的连接请求,然后创建一个 AIDL 文件,将暴露给客户端的接口在这个 AIDL 文件中声明,最后在 Service 中实现这个 AIDL 接口即可。
2 . 客户端
客户端首先要绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转换成 AIDL 接口所属的类型,就可以调用 AIDL 中的方法了。
3 . AIDL 接口的创建
创建一个 .aidl 文件,声明一个接口和一些方法,如:
// IBookManager.aidl package com.example.mac.processdemo.bean; import com.example.mac.processdemo.bean.Book; // Declare any non-default types here with import statements interface IBookManager { List<Book> getBookList(); void addBook(in Book book); }
AIDL 支持的数据类型
基本数据类型(int、long、char等 )
String 和 CharSequence
List:只支持ArrayList,里面的每个元素必须被 AIDL 支持
Map:只支持HashMap ,里面的每个元素都必须被 AIDL 支持,包括 key 和 value
Parcelable:所有实现了Parcelable接口的对象
AIDL:所有的 AIDL 接口本身也可以在 AIDL 文件中使用
注意:如果需要用到自定义的Parcelable对象,必须要新建一个同名的 AIDL 文件,并在其中声明它为Parcelable类型,例如:
// IBook.aidl package com.example.mac.processdemo.bean; parcelable Book;
4 . 远程服务端Service的实现
public class BookManagerService extends Service { private static final String TAG = "BMS"; // CopyOnWriteArrayList 支持并发读写 private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>(); // 需要返回的Binder对象 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); } @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } }; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onCreate() { super.onCreate(); mBookList.add(new Book(1, "Android")); mBookList.add(new Book(2, "IOS")); } }
5 . 客户端的实现
public class BookManagerActivity extends AppCompatActivity { private static final String TAG = "BokkManagerActivity"; private ServiceConnection coon = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { //绑定成功之后返回Binder对象,通过这个Binder对象得到IBookManager对象 IBookManager bookManager = IBookManager.Stub.asInterface(iBinder); try { List<Book> list = bookManager.getBookList(); Log.d(TAG, "query book list, list type: " + list.getClass().getCanonicalName()); Log.d(TAG, "query book list: " + list.toString()); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_book_manager); Intent intent = new Intent(this, BookManagerService.class); bindService(intent,coon,BIND_AUTO_CREATE); } @Override protected void onDestroy() { unbindService(coon); super.onDestroy(); } }
log日志
D/BokkManagerActivity: query book list, list type: java.util.ArrayList D/BokkManagerActivity: query book list: [Book{bookId=1, bookName='Android'}, Book{bookId=2, bookName='IOS'}]
稍作修改,现在客户端给服务端添加一本书,然后再获取一次。
private ServiceConnection coon = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { IBookManager bookManager = IBookManager.Stub.asInterface(iBinder); try { // 添加一本书 bookManager.addBook(new Book(3,"Android 开发艺术探索")); List<Book> list = bookManager.getBookList(); Log.d(TAG, "query book list, list type: " + list.getClass().getCanonicalName()); Log.d(TAG, "query book list: " + list.toString()); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { } };
log日志
D/BokkManagerActivity: query book list, list type: java.util.ArrayList D/BokkManagerActivity: query book list: [Book{bookId=1, bookName='Android'}, Book{bookId=2, bookName='IOS'}, Book{bookId=3, bookName='Android 开发艺术探索'}]
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories