1.7 AIDL 进程间通信

AIDL 进程间通信

AIDL 是英文 Android Interface Definition Language 的缩写。用于定义服务端和客户端通信接口的一种语言,可以用来生成IPC的代码。

Android 实现进程间通信(IPC)有很多种方式

  • 广播:占用的系统资源比较多,如果是频繁的跨进程通信的话显然是不可取的
  • Messenger: 进行跨进程通信时请求队列是同步进行的,无法并发执行,在有些要求多进程的情况下不适用
  • AIDL: 只有允许不同应用的客户端用 IPC 方式访问服务,并且想要在服务中处理多线程时,才有必要使用 AIDL。

1. AIDL 语法

  • AIDL文件以 .aidl 为后缀名
  • AIDL支持的数据类型分为如下几种:
    • 八种基本数据类型:byte、char、short、int、long、float、double、boolean 只支持in定向流(客户端到服务端)
    • String,CharSequence 只支持in定向流(客户端到服务端)
    • 实现了Parcelable接口的数据类型
    • List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
    • Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
  • AIDL文件可以分为两类。

    • 一类是用来定义接口方法,声明要暴露哪些接口给客户端调用
    • 一类用来声明实现了Parcelable接口的数据类型,以供其他AIDL文件使用那些非默认支持的数据类型。
  • 定向Tag。定向Tag表示在跨进程通信中数据的流向,用于标注方法的参数值,分为 in、out、inout 三种。

    • in 表示数据只能由客户端流向服务端
    • out 表示数据只能由服务端流向客户端
    • inout 数据可在服务端与客户端之间双向流通
  • 明确导包。在AIDL文件中需要明确标明引用到的数据类型所在的包名,即使两个文件处在同个包名下

2. AIDL 实现进程间通信实现步骤

服务端

  1. 创建AIDL接口文件中需要传输的数据类型的接口文件。创建对应的实体类实现Parcelable接口
// Book.aidl
package com.littlezan.interviewpractice.module.aidl;

// Declare any non-default types here with import statements

parcelable  Book ;
public class Book implements Parcelable {

    private String name;

    public Book(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
    }

    public void readFromParcel(Parcel dest) {
        name = dest.readString();
    }

    public Book() {
    }

    protected Book(Parcel in) {
        this.name = in.readString();
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        @Override
        public Book createFromParcel(Parcel source) {
            return new Book(source);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };
  1. 创建AIDL接口文件。
// IMyAidlBookInterface.aidl
package com.littlezan.interviewpractice.module.aidl;

// Declare any non-default types here with import statements
import com.littlezan.interviewpractice.module.aidl.Book;

interface IMyAidlBookInterface {

    List getBookList();

    void addBookInOut(inout Book book);
}
  1. 创建一个Service,用来和客户端通信
public class AIDLService extends Service {

    private static final String TAG = "AIDLService";

    private List bookList;

    public AIDLService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        bookList = new ArrayList<>();
        initData();
    }

    private void initData() {
        Book book1 = new Book("活着");
        Book book2 = new Book("或者");
        Book book3 = new Book("叶应是叶");
        Book book4 = new Book("https://github.com/leavesC");
        Book book5 = new Book("http://www.jianshu.com/u/9df45b87cfdf");
        Book book6 = new Book("http://blog.csdn.net/new_one_object");
        bookList.add(book1);
        bookList.add(book2);
        bookList.add(book3);
        bookList.add(book4);
        bookList.add(book5);
        bookList.add(book6);
    }

    private final IMyAidlBookInterface.Stub stub = new IMyAidlBookInterface.Stub() {

        @Override
        public List getBookList() throws RemoteException {
            return bookList;
        }

        @Override
        public void addBookInOut(Book book) throws RemoteException {
            if (book != null) {
                book.setName("服务器改了新书的名字 InOut");
                bookList.add(book);
            } else {
                Log.e(TAG, "接收到了一个空对象 InOut");
            }

        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }

客户端

  1. 复制服务端aidl接口文件及实体类到项目中。将 aidl 文件夹整个复制到和Java文件夹同个层级下,不需要改动任何代码
  2. 绑定Service进程通信
private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IMyAidlBookInterface bookController = IMyAidlBookInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
          
        }
    };

你可能感兴趣的:(1.7 AIDL 进程间通信)