IPC通信方式之AIDL使用

AIDL 是什么?
在Android开发中IPC(Inter-Process Communication的缩写)多进程通信的使用场景很多。一般地由于某些功能模块需要特殊原因运行在单独的进程中,又或者为了加大一个应用可使用的内存,因为Android对单个应用使用的最大内存是有限制的,又或者需要做一些非常耗内存而又不好回收的事情,在事情完成后直接结束掉进程,等。开启多进程模式很简单,就是给四大组件指定android:process属性即可。IPC的方式有多种,在日常开发中涉及进程间通信时的首选应该就是AIDL了。我们就来以示例的方式学习AIDL的使用。
AIDL 支持的数据类型

  • Java 的基本数据类型
  • List 和 Map(元素必须是 AIDL 支持的数据类型,Server 端具体的类里则必须是 ArrayList 或者 HashMap)
  • 其他 AIDL 生成的接口
  • 实现 Parcelable 的实体

AIDL 如何编写
AIDL 的编写主要为以下三部分:
1、创建 AIDL

  • 创建要操作的实体类,实现 Parcelable 接口,以便序列化/反序列化,客户端和服务端实体类和aidl包名要一样,或者会报错的
  • 新建 aidl 文件夹,在其中创建接口 aidl 文件以及实体类的映射 aidl 文件
  • Make project ,生成 Binder 的 Java 文件

2、服务端

  • 创建 Service,在其中创建上面生成的 Binder 对象实例,实现aidl接口定义的方法
  • 在 onBind() 中返回Binder 对象实例
    3、客户端
  • 实现 ServiceConnection 接口,在其中拿到 AIDL 类
  • bindService()
  • 调用 AIDL 类中定义好的操作请求,添加一个按钮,点击按钮后客户端传递参数给服务端返回的结果

代码示例
1、服务端

  • 首先创建一个实体People类并且实现Parcelable序列化
public class People implements Parcelable {
    private String name;
    private int age;

    public People(){

    }
    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //读写的顺序必须要一直
    public People(Parcel source) {
        this.name = source.readString();
        this.age = source.readInt();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int describeContents() {
        return 0;
    }
    //该方法是把该People中的变量写进Parcel对象中
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }
    public static final Creator<People> CREATOR = new Creator<People>() {
        @Override
        public People createFromParcel(Parcel source) {
            return new People(source);
        }

        @Override
        public People[] newArray(int size) {
            return new People[size];
        }
    };

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 新建 aidl 文件夹,在其中创建接口 aidl 文件以及实体类的映射 aidl 文件
    在这里插入图片描述先创建实体类的映射 aidl 文件People.aidl
// People.aidl
package com.wq.aidlserver;

// Declare any non-default types here with import statements

parcelable People;

  • 创建aidl.aidl文件
package com.wq.aidlserver;
import com.wq.aidlserver.People;

interface aidl {
   int add1(int num1,int num2);
   List<People> add(in People people);
}
  • 创建一个MyServer服务
public class MyServer extends Service {
    private static final String TAG = "wq892373445";
    private ArrayList<People> mPeople = null;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG,"onCreate()");
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG,"onUnbind()");
        return super.onUnbind(intent);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG,"onDestroy()");
    }

    @Override
    public IBinder onBind(Intent intent) {
        mPeople = new ArrayList<People>();
        Log.d(TAG,"onBind()");
        return iBinder;
    }
    private IBinder iBinder = new aidl.Stub() {
        @Override
        public int add1(int num1, int num2) throws RemoteException {
            Log.d(TAG,"add1:num1="+num1+"num2="+num2);
            return num1+num2;
        }

        @Override
        public List<People> add(People people) throws RemoteException {
            mPeople.add(people);
            return mPeople;
        }
    };

}

  • 在AndroidManifest.xml文件中注册服务
 <service android:name=".MyServer">
            <intent-filter>
                <action android:name="com.wq.aidlserver.MyServer"/>
            </intent-filter>
        </service>

2、客户端

  • 首先把服务端的aidl文件和实体类拷贝到客户端这边来,保持一致
    在这里插入图片描述
  • 在Activity中和服务端进程间通信
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "wq892373445";
    private aidl mAidl;
    private ServiceConnection conn = new ServiceConnection() {
        //服务连接上的时候调用这个方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG,"onServiceConnected()");
            //拿到了远程的服务
            mAidl = aidl.Stub.asInterface(service);
        }
        //当服务断开的时候调用这个方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG,"onServiceDisconnected()");
            //回收资源
            mAidl = null;
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //绑定服务
        bindServers();
    }
    //绑定服务
    public void onAidl(View view) {
        try {
            //调用远程aidl服务,这样就可以实现进程间通信了
            int res = mAidl.add1(2,3);
            Log.d(TAG,"客户端传递参数给服务端返回的结果:res="+res);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        try {
            ArrayList<People> mPeople = (ArrayList<People>) mAidl.add(new People("wang",12));
            Log.d(TAG,"mPeople   "+mPeople.toString());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    public void bindServers(){
        //获取到服务端
        Intent intent = new Intent();
        //显示Intent启动服务,5.0后必须这样启动服务
        intent.setComponent(new ComponentName("com.wq.aidlserver","com.wq.aidlserver.MyServer"));
        bindService(intent,conn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG,"onDestroy()");
        //解绑服务
        unbindService(conn);
        if(conn != null )
        {
            unbindService(conn);
            conn = null;

        }
    }
}

最后执行结果如下所示:

2020-04-11 22:20:20.017 4292-4292/com.wq.aidlserver D/wq892373445: onCreate()
2020-04-11 22:20:20.018 4292-4292/com.wq.aidlserver D/wq892373445: onBind()
2020-04-11 22:20:20.032 4803-4803/? D/wq892373445: onServiceConnected()
2020-04-11 22:20:24.210 4292-4317/com.wq.aidlserver D/wq892373445: add1:num1=2num2=3
2020-04-11 22:20:24.211 4803-4803/com.wq.aidlclient D/wq892373445: 客户端传递参数给服务端返回的结果:res=5
2020-04-11 22:20:24.215 4803-4803/com.wq.aidlclient D/wq892373445: mPeople   [People{name='wang', age=12}]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值