本技术博文计划分为三个系列:
一、AIDL的基础。
二、AIDL之Messenger,http://blog.csdn.net/wangqiubo2010/article/details/78615047
三、AIDL终极篇之AIDL架构设计,http://blog.csdn.net/wangqiubo2010/article/details/78625846。
一,AIDL的本质可以从以下来理解。
1、AIDL专门为android中的跨进程通讯设计。通过以下对其他跨进程通讯的几种方式的弱点来解析AIDL的优点。ContentProvider、Broadcast 这两种底层也是通过IBinder来实现,其使用范围为系统级的(重量级的),主要用于应用程序和JNI(本地方法库)之间通讯,例如系统通知、电话本、蓝牙等;sharepreference多线程对其读写会出现安全性问题,并且sharepreference有缓存数据;Socket通讯,主要用于网络;serializable序列化是重量级的,并且AIDL中跨进程传送也是序列化,只是这个序列化是轻量级的Parcelable。
2、AIDL的跨进程通讯本质为 IBinder。
3、AIDL文件最好是放在同一个包中,因为Client 和 service必须同时且完全拥有同一份AIDL文件,否则无法进行通讯。
4、传送对象必须实现Parcelable,并且这个对象需要定义一份AIDL文件,文件格式如下:
传送的对象类为Book.java,其需要另外定义一个Book.aidl文件,结构如下
package com.example.wangqiubo.myaidl;
parcelable Book;
5、服务端实现AIDL的本质是实现Stub ,例如IBooksAidlInterface.Stub 。
二、具体应用。
1、android studio定义一个AIDL文件,如下。
// IBooksAidlInterface.aidl
package com.example.wangqiubo.myaidl;
import com.example.wangqiubo.myaidl.Book;
import com.example.wangqiubo.myaidl.IBookCallBackInterface;
interface IBooksAidlInterface {
List<Book> getBookList();
void addBook(in Book book);
void registerBookEvent(IBookCallBackInterface bookEvent);
void unregisterBookEvent(IBookCallBackInterface bookEvent);
}
2、实现本AIDL借口,即是实现 IBooksAidlInterface.Stub。
//BookImpl.java
package com.example.myservice;
import android.os.RemoteException;
import com.example.wangqiubo.myaidl.Book;
import com.example.wangqiubo.myaidl.IBookCallBackInterface;
import com.example.wangqiubo.myaidl.IBooksAidlInterface;
import java.util.ArrayList;
import java.util.List;
public class BookImpl extends IBooksAidlInterface.Stub {
List<Book> books = new ArrayList<>();
@Override
public List<Book> getBookList() throws RemoteException {
return books;
}
@Override
public void addBook(Book book) throws RemoteException {
books.add(book);
}
@Override
public void registerBookEvent(IBookCallBackInterface bookEvent) throws RemoteException {
}
@Override
public void unregisterBookEvent(IBookCallBackInterface bookEvent) throws RemoteException {
}
}
3、拷贝一份IBooksAidlInterface.aidl到客户端,注意客户端的IBooksAidlInterface.aidl和服务端的必须完全一致,包括包名和源代码。
4、客户端链接服务,并且通过服务端传过来的IBinder转换成IBooksAidlInterface对象。
//BookClient .java
package com.example.wangqiubo.myapplication;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import com.example.wangqiubo.myaidl.IBooksAidlInterface;
/**
* Created by kingsoft on 2017/11/22.
*/
public class BookClient {
IBooksAidlInterface book;
public ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service{
book = IBooksAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
5、客户端拿到IBooksAidlInterface 对象,则就可以直接调用里面的方法了,其最后调用的就是在服务器端实现IBooksAidlInterface 类的方法。这里有一点需要注意,调用服务器的方式的时候,必须开区一个线程,在非UI线程中来获取结果。原因很简单,android如果5秒没反应就会出现ANR,因为是通过网络访问服务器的,所以得到结果的时间是未知的,并且调用服务器的方法时客户端会进行等待式阻塞,直到服务器的回应。
以上代码结构截图如下: