// Book.java public class Book implements Parcelable { public String bookName; public Book( String bookName ) { this.bookName = bookName; } @Override public int describeContents() { // TODO Auto-generated method stub return 0; } @Override public void writeToParcel(Parcel arg0, int arg1) { arg0.writeString(bookName); } public static final Parcelable.Creator< Book> CREATOR = new Creator<Book>() { @Override public Book[] newArray(int arg0) { // TODO Auto-generated method stub return new Book[arg0]; } @Override public Book createFromParcel(Parcel arg0) { // TODO Auto-generated method stub return new Book(arg0); } }; public Book( Parcel in ) { bookName = in.readString(); } }
//Book.aidl package com.zhenfei.aidl; parcelable Book;
//IBookManager.aidl package com.zhenfei.aidl; import com.zhenfei.aidl.Book; interface IBookManager{ List<Book> getBookList(); void addBook( in Book book); }
package com.zhenfei.aidl; public interface IBookManager extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.zhenfei.aidl.IBookManager { private static final java.lang.String DESCRIPTOR = "com.zhenfei.aidl.IBookManager"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.zhenfei.aidl.IBookManager interface, * generating a proxy if needed. */ public static com.zhenfei.aidl.IBookManager asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.zhenfei.aidl.IBookManager))) { return ((com.zhenfei.aidl.IBookManager)iin); } return new com.zhenfei.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<com.zhenfei.aidl.Book> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); com.zhenfei.aidl.Book _arg0; if ((0!=data.readInt())) { _arg0 = com.zhenfei.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 com.zhenfei.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<com.zhenfei.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<com.zhenfei.aidl.Book> _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArrayList(com.zhenfei.aidl.Book.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void addBook(com.zhenfei.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 {+*-999999999 _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public java.util.List<com.zhenfei.aidl.Book> getBookList() throws android.os.RemoteException; public void addBook(com.zhenfei.aidl.Book book) throws android.os.RemoteException; }
public class ServerService extends Service{ ArrayList<Book> books = new ArrayList<Book>(); private Stub stub = new Stub() { @Override public List<Book> getBookList() throws RemoteException { return books; } @Override public void addBook(Book book) throws RemoteException { books.add(book); } }; public void onCreate() { super.onCreate(); Book book1 = new Book( "第1本书"); Book book2 = new Book( "第2本书"); Book book3 = new Book( "第3本书"); books.add(book1); books.add(book2); books.add(book3); System.out.println( "有 "+ books.size() + " 本书"); }; @Override public IBinder onBind(Intent arg0) { return stub; } }
public class MainActivity extends Activity { IBookManager iBookManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent toNewIntent = new Intent(); toNewIntent.setAction( "com.zhenfei.myaidl"); bindService(toNewIntent, serviceConnection, Context.BIND_AUTO_CREATE); } public ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName arg0) { System.out.println( "onServiceDisconnected className :" + arg0.getClassName()) ; } @Override public void onServiceConnected(ComponentName arg0, IBinder arg1) { iBookManager = IBookManager.Stub.asInterface(arg1); System.out.println( "onServiceConnected "); List<Book> books; try { books = iBookManager.getBookList(); System.out.println( "客户端获得到: "+ books.size() + " 本书"); } catch (RemoteException e) { e.printStackTrace(); } } }; }
/** * Convenience method for associating a specific interface with the Binder. * After calling, queryLocalInterface() will be implemented for you * to return the given owner IInterface when the corresponding * descriptor is requested. */ public void attachInterface(IInterface owner, String descriptor) { mOwner = owner; mDescriptor = descriptor; }
/** * Use information supplied to attachInterface() to return the * associated IInterface if it matches the requested * descriptor. */ public IInterface queryLocalInterface(String descriptor) { if (mDescriptor.equals(descriptor)) { return mOwner; } return null; }
<span style="white-space:pre"> </span>android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.util.List<com.zhenfei.aidl.Book> _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArrayList(com.zhenfei.aidl.Book.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result;
@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.zhenfei.aidl.Book> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); com.zhenfei.aidl.Book _arg0; if ((0!=data.readInt())) { _arg0 = com.zhenfei.aidl.Book.CREATOR.createFromParcel(data); } else { _arg0 = null; } this.addBook(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); }
<span style="white-space:pre"> </span> java.util.List<com.zhenfei.aidl.Book> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result);
那么 client 和 server 都为 out
如果client只需要传输数据给server,而不需要处理返回的数据,
那么client和server都为 in
如果client需要传输数据给server,而且需要处理返回的数据,
则client和server都为 inout
好了,在这边Binder就先介绍到这里了,如果之后有对C++层和内核层的Binder机制进行学习,我会继续写下来。