出于玉刚的《Android开发艺术探索》2.3.3-Binder
Demo源码
-
Book.java
文件// 实体类 package com.chen.interview.aidl; import android.os.Parcel; import android.os.Parcelable; public class Book implements Parcelable { private int id; private String name; public Book(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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.writeInt(this.id); dest.writeString(this.name); } protected Book(Parcel in) { this.id = in.readInt(); 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]; } }; @Override public String toString() { return "Book{" + "id=" + id + ", name='" + name + '\'' + '}'; } } -
Book.aidl
文件package com.chen.interview.aidl; parcelable Book;
-
IBookManager.aidl
文件// IMyService.aidl package com.chen.interview.aidl; import com.chen.interview.aidl.Book; // 注意:就算在同一个包名下也需手动导入 // Declare any non-default types here with import statements interface IBookManager { List
getBookList(); void addBook(in Book book); } -
AS自动生成的
IBookManager.java
文件/* * This file is auto-generated. DO NOT MODIFY. * Original file: /Users/zehua_chen/Android/work/wrokspace/android/work_as/Interview/app/src/main/aidl/com/chen/interview/aidl/IBookManager.aidl */ package com.chen.interview.aidl; // Declare any non-default types here with import statements public interface IBookManager extends android.os.IInterface { /** * Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.chen.interview.aidl.IBookManager { // 唯一标识,一般用当前类名全称表示 private static final java.lang.String DESCRIPTOR = "com.chen.interview.aidl.IBookManager"; /** * Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * 用户将服务端的Binder对象转换成客户端所需的AIDL接口类型额对象 * 区分进程,如果服务端和客户端处于同一进程则返回服务端对象本身,否则返回Stub.Proxy对象 * * Cast an IBinder object into an com.chen.interview.aidl.IBookManager interface, * generating a proxy if needed. */ public static com.chen.interview.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.chen.interview.aidl.IBookManager))) { // 同一进程 return ((com.chen.interview.aidl.IBookManager) iin); } // 不同进程 return new com.chen.interview.aidl.IBookManager.Stub.Proxy(obj); } /** * 用于返回当前Binder对象 * * @return Binder */ @Override public android.os.IBinder asBinder() { return this; } /** * 该方法运行与服务端的Binder线程池中,客户端发起请求时,远程请求会通过系统底层封装后交给此方法处理 * @param code 确定客户端请求的目标方法 * @param data 可从data获取目标方法所需的参数 * @param reply 方法执行完会向reply写入返回值(如果有返回值) * @param flags 一些额外的标识,0表示正常的PRC,如果为 * {@link android.os.Binder#FLAG_ONEWAY}即为1,表示单向的RPC * @return 返回false则表示客户端请求失败 * @throws android.os.RemoteException */ @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
_result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); com.chen.interview.aidl.Book _arg0; if ((0 != data.readInt())) { _arg0 = com.chen.interview.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.chen.interview.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; } /** * 运行在客户端 * @return * @throws android.os.RemoteException */ @Override public java.util.List getBookList() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.util.List _result; try { _data.writeInterfaceToken(DESCRIPTOR); // transact发起RPC,当前线程挂起,然后服务端的onTransact方法会被调用 mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); // 直到PRC过程返回后,当前线程继续执行,若远程方式是耗时的,勿在主线程发起RPC请求 _reply.readException(); // 从_reply获取返回的数据 _result = _reply.createTypedArrayList(com.chen.interview.aidl.Book.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void addBook(com.chen.interview.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(); } } } 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 getBookList() throws android.os.RemoteException; public void addBook(com.chen.interview.aidl.Book book) throws android.os.RemoteException; }
IPC通信
-
服务端角色
BookManagerService.java
public class BookManagerService extends Service { private static final String TAG = "BMS"; private CopyOnWriteArrayList
mBookList = new CopyOnWriteArrayList<>(); private Binder mBinder = new IBookManager.Stub() { @Override public List getBookList() throws RemoteException { 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() { super.onCreate(); mBookList.add(new Book(1, "java")); mBookList.add(new Book(2, "C++")); mBookList.add(new Book(3, "python")); } } -
客户端角色
MainActivity.java
public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IBookManager bookManager = IBookManager.Stub.asInterface(service); try { bookManager.addBook(new Book(4, "算法")); List
bookList = bookManager.getBookList(); Log.i(TAG, "list type: " + bookList.getClass().getCanonicalName()); Log.i(TAG, "list: " + bookList); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, BookManagerService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, ProviderActivity.class)); } }); } @Override protected void onDestroy() { unbindService(mConnection); super.onDestroy(); }