天天看点

Android studio中创建aidl文件

新建aidl文件夹:

Android studio中创建aidl文件
Android studio中创建aidl文件

在新建里的aidl文件夹中新建Java文件:其中Book实现了parcelable接口

Android studio中创建aidl文件
Android studio中创建aidl文件

Book代码:

package cqupt.second.aidl;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {

    public int bookId;
    public String bookName;

    public Book() {

    }

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

    public int describeContents() {
        return 0;
    }

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

    public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

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

    @Override
    public String toString() {
        return String.format("[bookId:%s, bookName:%s]", bookId, bookName);
    }
}
           

创建aidl文件、创建Book.aidl、创建IBookManager.aidl:

Android studio中创建aidl文件
Android studio中创建aidl文件
Android studio中创建aidl文件

Book.aidl中的代码:

package cqupt.second.aidl;

parcelable Book;
           

IBookManager.aidl中的代码:

package cqupt.second.aidl;
import cqupt.second.aidl.Book;
interface IBookManager {
    List<Book> getBookList();
    void addBook(in Book book);
}
           

最终自动生成了IBookManager.java文件:

Android studio中创建aidl文件
Android studio中创建aidl文件

IBookManager.java中的代码:

package cqupt.second.aidl;

public interface IBookManager extends android.os.IInterface {
    public java.util.List<cqupt.second.aidl.Book> getBookList()
        throws android.os.RemoteException;

    public void addBook(cqupt.second.aidl.Book book)
        throws android.os.RemoteException;

    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements cqupt.second.aidl.IBookManager {
        private static final java.lang.String DESCRIPTOR = "cqupt.second.aidl.IBookManager";
        static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION +
            0);
        static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION +
            1);

        /** Construct the stub at attach it to the interface. */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an cqupt.second.aidl.IBookManager interface,
         * generating a proxy if needed.
         */
        public static cqupt.second.aidl.IBookManager asInterface(
            android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }

            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

            if (((iin != null) &&
                    (iin instanceof cqupt.second.aidl.IBookManager))) {
                return ((cqupt.second.aidl.IBookManager) iin);
            }

            return new cqupt.second.aidl.IBookManager.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_getBookList: {
                data.enforceInterface(DESCRIPTOR);

                java.util.List<cqupt.second.aidl.Book> _result = this.getBookList();
                reply.writeNoException();
                reply.writeTypedList(_result);

                return true;
            }

            case TRANSACTION_addBook: {
                data.enforceInterface(DESCRIPTOR);

                cqupt.second.aidl.Book _arg0;

                if ((0 != data.readInt())) {
                    _arg0 = cqupt.second.aidl.Book.CREATOR.createFromParcel(data);
                } else {
                    _arg0 = null;
                }

                this.addBook(_arg0);
                reply.writeNoException();

                return true;
            }
            }

            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements cqupt.second.aidl.IBookManager {
            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 java.util.List<cqupt.second.aidl.Book> getBookList()
                throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                java.util.List<cqupt.second.aidl.Book> _result;

                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_getBookList, _data,
                        _reply, 0);
                    _reply.readException();
                    _result = _reply.createTypedArrayList(cqupt.second.aidl.Book.CREATOR);
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }

                return _result;
            }

            @Override
            public void addBook(cqupt.second.aidl.Book book)
                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 ((book != null)) {
                        _data.writeInt(1);
                        book.writeToParcel(_data, 0);
                    } else {
                        _data.writeInt(0);
                    }

                    mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
        }
    }
}
           

其中:DESCRIPTOR是Binder的唯一标识,一般用当前Binder类名表示

    asInterface(android.os.IBinder obj):用于将服务端的Binder对象转换成客户端所需要的AILDL接口类型的对象,如果客户端与服务端在同一进程,返回服务端的Stub对象本身,否则返回系统封装后的Stub.proxy对象

    asBinder():返回当前Binder对象

    onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags):运行在服务端的Binder线程池中,当客户端发起进程间请求,远程请求会通过系统封装之后交由此方法处理。服务端通过code可以确定客户端请求的目标方法是什么,接着从data中取出目标方法所需要的参数(如果目标方法有参数的话),然后执行目标方法。放执行完毕之后,向reply中写入返回值(如果有返回值的话)

    Proxy类中的getBookList():客户端调用获取数据。将创建该方法所需要的参数:输入型Parcel对象_data、输出型Parcel对象_reply和返回值队形List写入该方法的参数_data中,然后调用transact方法发起RPC(远程过程调用)请求,同时线程被挂起,接着服务端调用onTransact()方法,RPC过程结束,当前线程继续执行,从_reply中取出RPC过程返回的数据,最后返回_reply中的数据

    Proxy类中的addBook(cqupt.second.aidl.Book book):客户端调用,过程与getBookList()类似

注意:客户端发起请求后,当前线程会被挂起,直到服务端进程返回数据。

    服务端的Binder方法运行在Binder线程池中。

Android studio中创建aidl文件

给Binder设置死亡代理:

private IBookManager mRemoteBookManager;
    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            if (mRemoteBookManager == null) {
                return;
            }
            mRemoteBookManager.asBinder().unlinkToDeath(mDeathRecipient, 0);
            mRemoteBookManager = null;
            // TODO: 2017/2/12 重新绑定service

        }
    };

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            IBookManager bookManager = IBookManager.Stub.asInterface(service);
            mRemoteBookManager = bookManager;
            try {
                mRemoteBookManager.asBinder().linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };