AIDL的基本使用(一)

来源:互联网 发布:李小冉 知乎 编辑:程序博客网 时间:2024/05/20 07:35

AIDL的基本使用

上一篇博客介绍了Messenger的使用,可以发现,Messenger适合用于进程间传递消息,那如果需要调用服务端的方法,这种情形就不适合使用Messenger了,而适合使用AIDL。AIDL的使用步骤较复杂,建议多练习并搞懂原理。

使用步骤

1.首先创建一个AIDL文件,将要暴露给客户端的接口写在AIDL文件中。在Android Studio中右键创建aidl文件,就会自动生成aidl包,把所有aidl文件都写在该包下即可。

// IBookManager.aidlpackage com.example.xin.aidldemo;import com.example.xin.aidldemo.Book;interface IBookManager {    List<Book> getBookList();    void addBook(in Book book);}

2.AIDL所支持的数据类型是有限的,有以下几种:基本数据类型,String和CharSequence, List的ArrayList, Map的HashMap, Parcelable,AIDL
上述代码中的Book对象需要实现Parcelable接口。而自定义的Parcelable需要写一个aidl文件声明,于是有两个文件需要写,一个是Book类,一个是声明Book类的aidl文件。

Book类:

public class Book implements Parcelable {    int mId;    String mName;    public int getId() {        return mId;    }    public String getName() {        return mName;    }    public Book(int id, String name){        mId = id;        mName = name;    }    protected Book(Parcel in) {        mId = in.readInt();        mName = in.readString();    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(mId);        dest.writeString(mName);    }    @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];        }    };}

声明Book类的aidl文件:

// Book.aidlpackage com.example.xin.aidldemo;parcelable Book;

以上文件中Book类的文件不要和aidl文件放在一起,否则会报找不到类的错误,放在正常的类文件位置即可。

3.Rebuild Project,可以在build文件夹下编译好的文件,具体文件内容后续再分析。至此,可以开始写服务端和客户端了。服务端程序使用Service,Service中实现接口方法并在onBind方法中将Stub对象返回。客户端调用时使用bindService,bindService的回调中会得到IBinder对象,使用Stub的asInterface将IBinder对象转化为接口IBookManager,即可在客户端调用服务端的方法。本案例中,Service运行在一个独立的进程,在Manifest文件中注册Service并指定进程名即可。

服务端代码:

public class BookManagerService extends Service {    private CopyOnWriteArrayList<Book> mBookList;    private Binder mBinder = new IBookManager.Stub() {        @Override        public List<Book> getBookList() throws RemoteException {            Log.d("ZXX","getBookList Service");            return mBookList;        }        @Override        public void addBook(Book book) throws RemoteException {            mBookList.add(book);        }    };    @Nullable    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    @Override    public void onCreate() {        mBookList = new CopyOnWriteArrayList<>();        mBookList.add(new Book(1,"测试"));        mBookList.add(new Book(2,"测试2"));    }}

客户端代码:

public class MainActivity extends AppCompatActivity {    private ServiceConnection serviceConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {            IBookManager bookManager = IBookManager.Stub.asInterface(iBinder);            try {                bookManager.addBook(new Book(3,"测试3"));                List<Book> list = bookManager.getBookList();                for(Book b : list){                    Log.d("ZXX",b.getName());                }            } catch (RemoteException e) {                e.printStackTrace();            }        }        @Override        public void onServiceDisconnected(ComponentName componentName) {        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Intent intent = new Intent(this, BookManagerService.class);        bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);    }}

Log分析:

Service 的log:
08-08 23:25:41.628 5026-5039/com.example.xin.aidldemo:creator D/ZXX: getBookList Service
说明客户端确实可以调用Service的接口实现
客户端的Log:
08-08 23:25:41.629 5009-5009/com.example.xin.aidldemo D/ZXX: 测试
08-08 23:25:41.629 5009-5009/com.example.xin.aidldemo D/ZXX: 测试2
08-08 23:25:41.629 5009-5009/com.example.xin.aidldemo D/ZXX: 测试3
客户端使用服务端的接口时和在客户端本身的接口并无差别,但实际运行则是在服务端运行。

注:本文内容参考Android开发艺术探索第二章AIDL部分。

原创粉丝点击