分享

AIDL的接触和使用

 Dragon_chen 2017-03-29
AIDL 全名 Android Interface Define Languange   用来建立进程间通信的接口,这里只介绍使用,不介绍原理。
首先要创建AIDL文件,定义AIDL接口,然后makeProject,在Production视图下gen目录能看到系统帮你生成的接口
定义AIDL接口注意的地方,接口中使用到的自定义类必须继承Parcelable,以支持序列化(在进程间传递的前提)接口继承Interface。自定义类作为AIDL接口必须声明是in或out或inout,输入输出类型参数。每引用一个其他类或者接口,都需要import。接口总使用的接口也必须是AIDL接口,接口监听数组使用RemotCallBackList,避免去除Listener出错,因为不是同一对象,传递的数据到另外一个进程生成一个新的相同的对象,要用Binder作为他们的唯一标识。onDestory时解除监听。
AIDL接口里的成员:
内部含有一个IBinder类型的Stub抽象类实现了定义的AIDL接口。主要使用这个来进行通信。Stub抽象类里还有一个Proxy代理类实现了定义的AIDL接口,不是同一个进程它就代替Stub进行通信。除此之外还有接口中定义的方法。
使用过程:
服务端:提供方法供调用的一端,建立一个Service,注册到ServiceManager中,里面声明一个Stub对象(Binder类型,在Service的onBind方法中返回此对象),
客户端:建立ServiceConnection实例,在onServiceConnected函数中的参数就是Service的onBind方法返回的对象。使用Stub对象的静态asInterface方法返回所定义的AIDL接口对象(因为Stub对象实现了AIDL接口)。就可以调用AIDL接口对象的定义的方法。onServiceConected函数是运行在UI线程中,所以不要做太耗时的操作。
最后bindService,
如果有多个AIDL接口要使用可以设计一个BinderPool,先返回一个Binder,它的接口方法就是根据参数不同返回其他Binder。
package com.example.administrator.test.aidl;
public interface IOnNewBookArrivedListener extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.administrator.test.aidl.IOnNewBookArrivedListener
{
private static final java.lang.String DESCRIPTOR = "com.example.administrator.test.aidl.IOnNewBookArrivedListener";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.administrator.test.aidl.IOnNewBookArrivedListener interface,
* generating a proxy if needed.
*/
public static com.example.administrator.test.aidl.IOnNewBookArrivedListener asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.administrator.test.aidl.IOnNewBookArrivedListener))) {
return ((com.example.administrator.test.aidl.IOnNewBookArrivedListener)iin);
}
return new com.example.administrator.test.aidl.IOnNewBookArrivedListener.Stub.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_onNewBookArrived:
{
data.enforceInterface(DESCRIPTOR);
com.example.administrator.test.aidl.Book _arg0;
if ((0!=data.readInt())) {
_arg0 = com.example.administrator.test.aidl.Book.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.onNewBookArrived(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.administrator.test.aidl.IOnNewBookArrivedListener
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public void onNewBookArrived(com.example.administrator.test.aidl.Book newBook) 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 ((newBook!=null)) {
_data.writeInt(1);
newBook.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_onNewBookArrived, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_onNewBookArrived = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public void onNewBookArrived(com.example.administrator.test.aidl.Book newBook) throws android.os.RemoteException;
}
public class BookManagerService extends Service {
private static final String TAG = "BMS";
private CopyOnWriteArrayList<Book>mBookList = new CopyOnWriteArrayList<>();
private RemoteCallbackList<IOnNewBookArrivedListener>mListener=new RemoteCallbackList<>();
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);
int count = mListener.getRegisteredCallbackCount();
Log.v("sss",count+"");
mListener.beginBroadcast();
for(int i=0;i<count;i++)
{
mListener.getBroadcastItem(i).onNewBookArrived(book);
}
mListener.finishBroadcast();
}

@Override
public void registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
mListener.register(listener);
}

@Override
public void unregisterListener(IOnNewBookArrivedListener listener) throws RemoteException {
mListener.unregister(listener);
}

};

@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
private IOnNewBookArrivedListener mlistener = new IOnNewBookArrivedListener.Stub() {
@Override
public void onNewBookArrived(Book newBook) throws RemoteException {
Log.v("sss","书到了!"+newBook.bookName);
}
};
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iBookManager = IBookManager.Stub.asInterface(service);
List<Book>list= null;
try {
list = iBookManager.getBookList();
Log.i("sss","listtype"+list.getClass().getCanonicalName());
iBookManager.registerListener(mlistener);
} catch (RemoteException e) {
e.printStackTrace();
}
try {
iBookManager.addBook(new Book(1,"我日"));
} catch (RemoteException e) {
e.printStackTrace();
}
}
Intent intent = new Intent(this,BookManagerService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多