AIDL学习笔记

简介

最近重温了下开发艺术探索里面的IPC机制,对于AIDL做下笔记

使用时,客户端定义AIDL接口方法

package com.lpc.aidltest;

// Declare any non-default types here with import statements
import com.lpc.aidltest.Book;

interface IBookInterface {
    List<Book> getBookList();
    void addBook(in Book book);
}

以及Parcelable数据类:

public class Book implements Parcelable {

    int bookId ;
    String bookName;


    protected Book(Parcel in) {
        bookId = in.readInt();
        bookName = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(bookId);
        dest.writeString(bookName);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    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];
        }
    };
}

编译后,系统生成AIDL实现的android.os.IInterface Java类—-IBookInterface,里面asBinder返回一个IBinder对象:
这里写图片描述
这个接口实现类,里面定义了2个空方法和一个Binder类型的Stub类,Stub类实现了外部类IBookInterface,原本需要重写getBookList和addBook方法,但是由于它是abstract类型的,所以实际上这个两个方法都是放在Stub的私有静态类Proxy里重写的,故而Proxy也实现了IBookInterface接口。
这里写图片描述

asInterface里面,根据客户端和服务器是否在同一进程,分别返回服务端的IBinder ,也就是Stub本身和客户端使用的IBinder–Proxy:

public static com.lpc.aidltest.IBookInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.lpc.aidltest.IBookInterface))) {
return ((com.lpc.aidltest.IBookInterface)iin);
}
return new com.lpc.aidltest.IBookInterface.Stub.Proxy(obj);
}

Proxy里面存有一个服务端的IBinder对象mRemote
这里写图片描述

1、不在同一进程时
调用的时Proxy里面的getBookList和addBook方法,都会使用服务端的IBinder实例mRemote的transact方法:

@Override public java.util.List<com.lpc.aidltest.Book> getBookList() throws android.os.RemoteException
{
//输入对象_data
android.os.Parcel _data = android.os.Parcel.obtain();
//输出结果_reply
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<com.lpc.aidltest.Book> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
//调用服务端,也就是Stub的onTransact,传入_data,返回_reply
mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArrayList(com.lpc.aidltest.Book.CREATOR);
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

通过transact的源码可以知道,实际上就是调用了Stub的onTransact方法。

2、在同一进程时
asInterface直接返回服务端的IBinder,也就是Stub,虽然Stub也实现了IBookInterface接口,但是由于它是abstract类型的,所以没有重写getBookList和addBook方法,而是直接通过onTransact来实现。

@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<com.lpc.aidltest.Book> _result = this.getBookList();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
case TRANSACTION_addBook:
{
data.enforceInterface(DESCRIPTOR);
com.lpc.aidltest.Book _arg0;
if ((0!=data.readInt())) {
_arg0 = com.lpc.aidltest.Book.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.addBook(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}

在onTransact里面通过方法对于的Flag来分别实现getBookList和addBook方法,在客户端请求transact方法时,线程回挂起,然后服务端onTransact执行,返回结果后,线程继续执行,从reply里面拿到结果。

最后看一段使用代码:

IBookManager bookManager = IBookManager.Stub.asInterface(service);
mRemoteBookManager.asBinder().linkToDeath(mDeathRecipient, 0);
List<Book> list = bookManager.getBookList();
Book newBook = new Book(3, "Android进阶");
bookManager.addBook(newBook);

上面的代码,总结下来就是:客户端定义AIDL方法(IBookManager.aidl),然后系统生成IBinder类(IBookManager.java),里面有服务端Stub和客户端Proxy,客户端通过IBinder类的Stub里面的asInterface拿到Proxy代理接口,调用接口里的getBookList方法,唤起服务端的onTransact方法,进行数据的操作,然后将结果放入reply中,返回给Proxy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值