深入解读Android的内部进程通信接口AIDL

2019-12-10 18:08:27王振洲

补充一点:out和in参数区别其实很明显我们直接查看adt生成在gen目录下对应的java文件就可以看出区别:当是out参数的时候是执行完之后从parcel对象读取值,而in参数时是写到parcel对象里面传过去。
我们看下当testMethod分别是out和in修饰时生成的文件
当时out的时候是从parcel对象里面读数据

mRemote.transact(Stub.TRANSACTION_testMethod, _data, _reply, 0);
_reply.readException();
if ((0!=_reply.readInt())) {
params.readFromParcel(_reply);
}

当时in的时候是从parcel对象里面取数据

if ((params!=null)) {
_data.writeInt(1);
params.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_testMethod, _data, _reply, 0);
_reply.readException();

(2)实现一个服务类用来实现进程之间通信MyAidlService.java,贴出部分代码,详细代码会在后面上传。

@Override
  public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    Log.d(TAG, "MyAidlService onBind");
    return mBinder;
  }
 
  private final IMyAidlService.Stub mBinder = new IMyAidlService.Stub() {
    private AIDLCallback cb;
 
    @Override
    public void saveDemoInfo(DemoParcelable demo) throws RemoteException {
      if (demo != null) {
        if ("meinv1".equals(demo.getDemo_name())) {
          demo.setDemo_name("meinv2");
        }
        list.add(demo);
        Log.d(TAG, "saveDemoInfo list.size = " + list.size() + " list = " + list);
        cb.returnResult(list, 5);
        Bundle params = new Bundle();
        cb.testMethod(params);
        int width = params.getInt("width", 0);
        int height = params.getInt("height", 0);
        Log.d(TAG, "width = " + width + " height = "+height);
      }
    }
 
    @Override
    public void registerClient(AIDLCallback cb) throws RemoteException {
      cb.asBinder().linkToDeath(new DeathRecipient() {
        @Override
        public void binderDied() {
          try {
            Log.i(TAG, "[ServiceAIDLImpl]binderDied.");
          } catch (Throwable e) {
          }
        }
      }, 0);
    }
  };