关于AIDL数据类型的Java篇

74 阅读4分钟

📦 ​​AIDL是什么?​

想象你要给隔壁楼的小伙伴传纸条,但你们用不同的语言写字。这时候就需要一个"翻译纸条的协议"——这就是AIDL(Android接口定义语言)。它帮不同APP之间"说同一种话",实现跨进程通信。


📚 ​​AIDL支持的数据类型​

🔍 ​​类型支持对照表​

数据类型快递比喻是否支持注意事项
基本类型小件包裹直接使用
String/CharSequence信件自动转码
List/Map标准货箱实际收到ArrayList/HashMap
Parcelable定制包装箱必须实现接口
AIDL接口跨站对讲机需单独定义.aidl文件
FileDescriptor保险箱钥匙需用ParcelFileDescriptor包装
IBinder员工通行证直接传递原始Binder对象
基本类型数组整箱矿泉水int[]、long[]等直接支持
Parcelable数组定制货箱集装箱需元素实现Parcelable

🎓 ​​自定义包裹教学:Student类​

想寄送学生信息?需要三步:

  1. ​实现Parcelable接口​​(给档案袋贴快递单)
java
Copy
public class Student implements Parcelable {
    int age;
    String name;
    // 必须实现打包/解包方法
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(age);
        dest.writeString(name);
    }
    // 创建解包工具
    public static final Creator<Student> CREATOR = ...;
}
  1. ​声明.aidl文件​​(告诉快递公司这个包裹怎么处理)
java
Copy
parcelable Student; // 就像在快递单上写"易碎品"

🏪 ​​服务端开店指南​

  1. ​继承Stub类​​(就像开店要准备商品)
java
Copy
public class HelloService extends IHelloService.Stub {
    // 实现各种服务方法
    public int printStudent(Student student) {
        Log.d(TAG, "收到学生:" + student.name);
    }
}
  1. ​注册服务​​(挂招牌)
java
Copy
ServiceManager.addService("hello", new HelloService()); // 在服务大厅挂上"hello"招牌

🛒 ​​客户端购物指南​

  1. ​找服务​​(按招牌找店)
java
Copy
IBinder binder = ServiceManager.getService("hello"); // 找到"hello"店铺
IHelloService svr = IHelloService.Stub.asInterface(binder); // 拿到购物小票
  1. ​疯狂下单​​(调用各种方法)
java
Copy
// 寄送普通包裹
svr.sayhello_to("老王");

// 寄送定制包裹
Student stu = new Student();
stu.name = "小明";
svr.printStudent(stu);

// 寄送集合包裹
List<String> wishList = new ArrayList<>();
wishList.add("想要PS5");
svr.printList(wishList);

🔧 ​​编译运行小贴士​

  1. aidl命令生成通信代码(自动生成翻译手册)
  2. 把服务端和客户端打包成jar(就像把店铺和顾客APP分开)
  3. 通过ADB命令启动(模拟两个APP的通信)

💡 ​​关键理解​

📚 ​​原来 Binder 支持这么多数据类型!​​ 让我们用快递站的比喻来分类理解这些"包裹类型"的用途:


​🚚 基础小件包裹(基本类型)​

  • ​类型​​:booleanbytecharintlongfloatdouble

  • ​特点​​:轻量高效,像寄送数字纸条

  • ​示例​​:

    java
    Copy
    service.setSwitch(true);      // 开关状态
    service.sendCode(1001);       // 状态码
    service.calculate(3.14, 2.0); // 浮点运算
    

​📨 标准文件袋(常用对象)​

  • ​String​​:文字信息(如用户昵称)
  • ​List​​:有序集合(购物清单)
  • ​FileDescriptor​​:文件句柄(快递保险箱钥匙)
  • ​PersistableBundle​​:持久化数据包(带封条的文件袋)

​🎁 定制包裹(Parcelable对象)​

  • ​android.os.Parcelable​​:必须实现打包/解包方法

  • ​实战场景​​:

    java
    Copy
    // 定义用户信息包裹
    public class User implements Parcelable {
        String name;
        int age;
        // 实现 writeToParcel 和 CREATOR
    }
    // 跨进程传递
    service.updateUser(user);
    

​🔑 特权通行证(Binder相关)​

  • ​T extends IBinder​​:传递 Binder 对象本身

  • ​使用场景​​:

    java
    Copy
    // 传递系统服务的 Binder 引用
    IBinder clipboardBinder = service.getSystemBinder();
    // 获得剪贴板服务代理
    IClipboard clipboard = IClipboard.Stub.asInterface(clipboardBinder);
    

​📦 集装箱货柜(数组与泛型)​

  • ​Arrays (T[])​​:支持基本类型和 Parcelable 数组

  • ​注意​​:

    java
    Copy
    // 正确用法
    int[] ids = {1001, 1002, 1003};
    Student[] students = new Student[3];
    // 错误用法(需用 ArrayList 替代)
    // List<String> list = Arrays.asList("A", "B"); 
    

​💡 为什么需要这么多类型?​

  1. ​效率优化​​:基本类型直接传递二进制数据,无需序列化
  2. ​场景覆盖​​:从简单状态到复杂对象,从临时数据到持久化存储
  3. ​系统集成​​:PersistableBundle 用于系统级数据持久化,FileDescriptor 实现高效文件传输

​🚀 开发指南​

  • ​选型策略​​:

    • 简单数据 → 基本类型
    • 复杂对象 → 实现 Parcelable
    • 跨服务调用 → 传递 IBinder
    • 大文件 → FileDescriptor
  • ​避坑技巧​​:

    • 避免传递大数据量的数组(改用分块传输)
    • 谨慎传递 IBinder(需权限校验)
    • PersistableBundle 适合系统备份场景

这些类型共同构成了 Android 跨进程通信的"物流网络",让数据像快递包裹一样安全高效地穿梭于应用之间!🎯