IPC实现方式

上一节总结了下IPC的基础概念,这一节主要介绍下IPC的实现方式,下面先通过一张图来了解下IPC有哪些方式:

在这里插入图片描述

通过上面这张图我们可以知道,IPC方式实际上都是通过Binder来实现的,只不过封装方式不同,下面我们再通过一张表,来了解下IPC不同方式之间的区别:

在这里插入图片描述通过上面这张表,我们对IPC不同方式有了个大概的了解,下面我们具体来介绍每种方式的使用。

一.Bundle

Bundle用于四大组件间的进程间通信,通过Intent.putExtra()传递Bundle数据,因为Bundle实现了Parcelable接口,所以它能很方便的在进程间传输,它不仅可以传输基本数据类型,还可以传输实现了Parcelable或Serializable接口的对象。

        Intent intent = new Intent(this, PersonService.class);
        Bundle bundle = new Bundle();
        bundle.putString("name","张三");
        bundle.putInt("age",12);
        bundle.putParcelable("person",new Person("王二麻子",13));
        intent.putExtra("bundle",bundle);
        bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);

二.文件共享

两个进程通过读/写同一个文件来交换数据,这种方式适用于对数据同步要求不高的进程之间进行通信,并且要妥善处理并发读/写的问题。另外SharedPreference是个特例,它底层基于xml实现,系统对于它的读写基于缓存,因此多进程模式下,读写变得不可靠,可能丢失数据。

三.AIDL

1.概念

android接口定义语言,如果在一个进程中要调用另外一个进程中对象的方法,可使用AIDL生成可序列化的参数,AIDL会生成一个服务端对象的代理类,客户端通过它实现间接调用服务端对象的方法。

2.支持的数据类型

  • 基本数据类型:byte、int、long、float、double、boolean、char
  • String类型
  • CharSequence类型
  • List类型,且里面的元素都能被AIDL支持
  • Map类型,且里面的元素都能被AIDL支持
  • 实现Parcelable接口的对象
  • 所有AIDL接口本身

注意:除了基本数据类型,其它类型参数必须标上方向:in、out、inout,用于表示跨进程通信中数据的流向,具体的区别在于:

in:表示数据只能由客户端流向服务端
out:表示数据只能由服务端流向客户端
inout:表示数据可在服务端和客户端之间双向流动

3.使用步骤

(1)创建数据实体类,实现Parcelable接口

(2)创建实体类的aidl声明

(3)创建aidl接口,表示服务端对外提供的能力

(4)服务端代码的实现

(5)客户端代码的实现

4.案例解析

(1)创建Person.java实体类,实现Parcelable接口

public class Person implements Parcelable {

    private String name;
    private int age;
	//Parcel是IBinder发送消息的容器,实现对象数据在内存中的传递
    protected Person(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

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

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }
    
    public void readFromParcel(Parcel dest) {
        name = dest.readString();
        age = dest.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;
    }

    public Person(String name , int age){
        this.name = name;
        this.age = age;
    }

}

(2)创建Person类的aidl声明

// Person.aidl
package com.czy.aidldemo;

parcelable Person ;

(3)创建IPersonManager接口

// IPersonManager.aidl
package com.czy.aidldemo;
import com.czy.aidldemo.Person;

interface IPersonManager {
   void addPerson(inout Person person);
    List<Person> getPersonList();
}

注意:

a.实体类的包名与AIDL文件的包名必须一致。

b.IPersonManager中必须import导入所需实体类。

c.接口中声明的方法参数需要使用in/out/inout。

d.实体类和aidl文件在两端都要有,且在同一包名下。

(4)编译项目,自动生成IPersonMa

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值