IPC之AIDL

简介
  IPC机制:进程间通信(Inter Process Communication的缩写);进程具有独立的资源空间,Android系统为每个进程都分配一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,导致不同虚拟机中访问同一个对象,会产生多个不同的数据副本;所以不同的进程之间无法共享数据,需要IPC机制跨进程通讯,相互传递数据。
IPC方式:Bundle,共享文件,广播,ContentProvider,Messager,AIDL,Socket七种方式;主要介绍AIDL通信的数据传递,分为两种情况:1)Activity向远程Service传递数据;2)远程Service向Activity传递数据。
AIDL是Android Interface Definition Language的缩写,AnDroid接口定义语言,在了解AIDL之前需要先了解Service的用法和Android序列化;
如何书写AIDL文件

IPC之AIDL
通过上图的方式,可以直接创建一个AIDL文件;可以根据自己的需求,定义方法
//Activity 向Service传递数据
interface IMyAidlInterface {
    void set(String str);//传递数据
}
开启远程服务
在充分了解普通Service的用法之后,跨进程开启Service也就很简单,不太了解Service的用法可先阅读Service的常见用法分析
1 定义一个类继承Service,并且在manifests加上android:process=":****"(android:process=":remote")新的进程
2 startService(),stopService();bindService(),unbindService和正常Service的调用一样;
bindService()方式开启远程Service,并且传递数据
Activity端:
private ServiceConnection serviceConnection = new ServiceConnection() {
   @Override
   public void onServiceDisconnected(ComponentName name) {
    Log.d(TAG, "onServiceDisconnected");
    try {
      myAIDLServie = null;
    } catch (RemoteException e) {
      e.printStackTrace();
    }
  }
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
    myAIDLServie = IMyAidlInterface.Stub.asInterface(service);
    try {
      myAIDLServie.set("远程传递数据");
    } catch (RemoteException e) {
      e.printStackTrace();
    }
  }
}
Service端
IMyAidlInterface.Stub iBinder = new IMyAidlInterface.Stub() {
   @Override
   public void set(String str) {
     Log.d(TAG, str);
     //todo 做操作
   }
};
以上是Activity通过AIDL向远程Service传递数据;
远程Service如何Activity传递数据呢?
主要有两种方式:1:广播;2:AIDL回调
主要介绍AIDL回调向Activity传递数据
1:定义一个AIDL文件,并且要在IMyAidlInterface.aidl中加入注册和反注册方法;
//用于Service 通知 Activity 的回调
interface ITaskCallback {
  void setData(int data);
}
IMyAidlInterface.aidl添加注册,反注册方法
//Activity 向Service传递数据
interface IMyAidlInterface {
  void set(String str);
  void registerCallback(ITaskCallback iTaskCallback);
  void unregisterCallback(ITaskCallback iTaskCallback);
}
Activity端
private ServiceConnection serviceConnection = new ServiceConnection() {
  @Override
  public void onServiceDisconnected(ComponentName name) {
    Log.d(TAG, "onServiceDisconnected");
    try {
      myAIDLServie.unregisterCallback(callback);
      myAIDLServie = null;
    } catch (RemoteException e) {
      e.printStackTrace();
    }
  }
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
    myAIDLServie = IMyAidlInterface.Stub.asInterface(service);
    try {
      myAIDLServie.registerCallback(callback);
      myAIDLServie.set("远程传递数据");
    } catch (RemoteException e) {
     e.printStackTrace();
    }
  }
};
//Service 传递过来的数据的回调
privateITaskCallback.Stubcallback=new ITaskCallback.Stub() {
  @Override
  public voidsetData(intdata)throwsRemoteException {
   Log.d(TAG,"setData::"+ data);
  }
};
Service端
/**
*一个容器,容纳的对象是一些接口,用于执行列表中对象的回调函数,主要用于服务调用activity函数,或者解释为服务端和客户端通信。
*线程同步 在Activity销毁时 会自动反注册
*/
privateRemoteCallbackList<ITaskCallback>mCallbacks=new RemoteCallbackList<ITaskCallback>();

IMyAidlInterface.Stub iBinder = new IMyAidlInterface.Stub() {
  @Override
  public void set(String str) {
    Log.d(TAG, str);
    callback();
  }
  @Override
  public void registerCallback(ITaskCallback iTaskCallback) throws RemoteException {
    Log.d(TAG, "registerCallback");
    if (iTaskCallback != null) {
      mCallbacks.register(iTaskCallback);
    }
  }
  @Override
  public void unregisterCallback(ITaskCallback iTaskCallback) throws RemoteException {
    if (iTaskCallback != null) {
      mCallbacks.unregister(iTaskCallback);
    }
  }
}
private voidcallback() {
  final intN =mCallbacks.beginBroadcast();
  for(inti = 0;i < N;i++) {
    try{
      mCallbacks.getBroadcastItem(i).setData(1);
    }catch(RemoteException e) {
      e.printStackTrace();
    }
  }
  mCallbacks.finishBroadcast();
}
以上就是远程Service通过AIDL调用Activit的方法或者向Activity传递数据的方法;


如有问题,请多指教