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文件

通过上图的方式,可以直接创建一个AIDL文件;可以根据自己的需求,定义方法

Activity 向Service传递数据

interface IMyAidlInterface {
    void set(String str);//传递数据
}

开启远程服务

在充分了解普通Service的用法之后,跨进程开启Service也就很简单,不太了解Service的用法可先阅读Service的常见用法分析

1 定义一个类继承Service,并且在manifests加上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传递数据的方法;

 

源码

 

如有问题,请多指教

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值