美文网首页
Android IPC之AIDL

Android IPC之AIDL

作者: CodeDuan | 来源:发表于2021-03-05 15:47 被阅读0次

在前面的文章中介绍了Messenger,Messenger的缺点就是一次只能处理一条消息,不支持多并发,而且只支持数据的传输,不支持方法的调用。那么在这一篇文章中 将为大家介绍更强大的IPC工具,AIDL。

AIDL 全称为Android Interface Definition Language,安卓接口定义语言,也是Android实现IPC的方式之一。接下来将为大家介绍AIDL的使用。

服务端:
服务端需要创建一个Service监听客户端的连接,并创建AIDL文件,将暴漏给客户端的方法在这个文件中声明。最后在Service中实现AIDL中的方法。

客户端:
绑定服务端的Service,并将Binder对象转欢为AIDL的接口类型。

首先我们创建一个AIDL接口(Android Studio中通过New-> AIDL-> aidl file)

import com.ipc.www.Book;//必须显式import

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

根据上面的代码,AIDL中实现了两个方法,获取Book列表和添加Book,
这里需要注意的有两点:
1、Book为实现了Parcelable的实体类。需要注意的是Book类必须import进来,无论是否在同一个包中。
2、在AIDL文件的接口方法中,如果参数为实现了Parcelable的接口类的话,参数必须标注方向,in、out、inout。

Book.class

public class Book implements Parcelable {
    private int bookId;
    private String bookName;

    public Book(int bookId,String bookName){
        this.bookId = bookId;
        this.bookName = bookName;
    }

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

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

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

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

    @Override
    public String toString() {
        return "Book{" +
                "bookId=" + bookId +
                ", bookName='" + bookName + '\'' +
                '}';
    }
}

另外,如果AIDL文件中用到了自定义的Parcelable对象时,则必须创建和他同名的AIDL文件,并声明为Parcelable类型,例如Book类,Book.aidl 代码如下。

parcelable Book;

至此AIDL文件已经创建完毕,接下来看服务端的实现。

public class BookManagerService extends Service {
    private static final String Tag = "BookManagerService";
    //bookList
    private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();

    // 创建Binder 实现IBookManager AIDL中的方法 并通过OnBind返回这个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);
            Log.i(Tag,mBookList.toString());
        }
    };

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

客户端的实现。

public class AidlActivity extends AppCompatActivity {

    private static final String Tag = "AidlActivity";

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //将Binder 转换为AIDL的接口类型 即可调用aidl中的方法
            IBookManager bookManager = IBookManager.Stub.asInterface(iBinder);
            try {
                //添加一本书
                Book book = new Book(1,"我是一本书");
                bookManager.addBook(book);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl);
        //绑定Service
        Intent intent = new Intent(this, BookManagerService.class);
        bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
    }
}

运行上述代码,可以看到控制台中成功输出了我们添加的内容(图1)。


图1

细心的小伙伴可能会问了,为什么mBookList使用CopyOnWriteArrayList而不用List呢?
这是因为CopyOnWriteArrayList支持高效率并发且是线程安全的,在AIDL中,难免会存在多线程同时访问的情况,所以在AIDL的方法中就需要做线程同步,而使用CopyOnWriteArrayList恰恰为我们省去了这部分工作。

AIDL中传输数据都支持哪些类型呢?

1、基本数据类型;
2、String和CharSequence;
3、ArrayList,HashMap,且其中的每个元素必须能够被AIDL支持。
4、实现了Parcelable的对象。
5、AIDL接口本身。

相关文章

网友评论

      本文标题:Android IPC之AIDL

      本文链接:https://www.haomeiwen.com/subject/kswrqltx.html