美文网首页
[Android笔记] IPC系列之AIDL

[Android笔记] IPC系列之AIDL

作者: Zach_C | 来源:发表于2019-01-11 01:42 被阅读1次

    出于玉刚的《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<Book> CREATOR = new Parcelable.Creator<Book>() {
              @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<Book> 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<com.chen.interview.aidl.Book> _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<com.chen.interview.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.chen.interview.aidl.Book> _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<com.chen.interview.aidl.Book> 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<Book> mBookList = new CopyOnWriteArrayList<>();
      
          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);
              }
          };
      
          @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<Book> 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();
          }
      

    相关文章

      网友评论

          本文标题:[Android笔记] IPC系列之AIDL

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