Android多进程开发 - AIDL 参数方向、AIDL 传递自定义对象、AIDL 传递自定义对象(参数方向)

一、AIDL 参数方向

1、基本介绍
  • 在 AIDL 中,引用类型参数必须明确指定方向
方向 说明
in 服务端使用客户端传入的参数(最常用)
out 服务端填充客户端传入的参数
inout 服务端使用客户端传入的参数,并重新填充
2、演示
(1)AIDL
java 复制代码
package com.my.common;

interface IMyAidlInterface {
    void data_in(in byte[] data);
    void data_out(out byte[] data);
    void data_inout(inout byte[] data);

    void list_in(in List<String> list);
    void list_out(out List<String> list);
    void list_inout(inout List<String> list);
}
(2)Server
java 复制代码
private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

    @Override
    public void data_in(byte[] data) throws RemoteException {
        Log.i(TAG, "data_in input: " + Arrays.toString(data));

        data[0] = 101;
        data[1] = 102;
    }

    @Override
    public void data_out(byte[] data) throws RemoteException {
        Log.i(TAG, "data_out input: " + Arrays.toString(data));

        data[0] = 101;
        data[1] = 102;
    }

    @Override
    public void data_inout(byte[] data) throws RemoteException {
        Log.i(TAG, "data_out input: " + Arrays.toString(data));

        data[0] = 101;
        data[1] = 102;
    }

    @Override
    public void list_in(List<String> list) throws RemoteException {
        Log.i(TAG, "list_in input: " + list);

        list.add("server item1");
        list.add("server item2");
    }

    @Override
    public void list_out(List<String> list) throws RemoteException {
        Log.i(TAG, "list_out input: " + list);

        list.add("server item1");
        list.add("server item2");
    }

    @Override
    public void list_inout(List<String> list) throws RemoteException {
        Log.i(TAG, "list_inout input: " + list);

        list.add("server item1");
        list.add("server item2");
    }
};
(3)Client Test
  1. data_in 方法
java 复制代码
byte[] data = new byte[2];
data[0] = 1;
data[1] = 2;

try {
    myAidlInterface.data_in(data);
    Log.i(TAG, "data_in method success");
    Log.i(TAG, "after data: " + Arrays.toString(data));
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "data_in method error: " + e.getMessage());
}
复制代码
# Server

data_in input: [1, 2]

# Client

data_in method success
after data: [1, 2]
  1. data_out 方法
java 复制代码
byte[] data = new byte[2];
data[0] = 1;
data[1] = 2;

try {
    myAidlInterface.data_out(data);
    Log.i(TAG, "data_out method success");
    Log.i(TAG, "after data: " + Arrays.toString(data));
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "data_out method error: " + e.getMessage());
}
复制代码
data_out input: [0, 0]

data_out method success
after data: [101, 102]
  1. data_inout 方法
java 复制代码
byte[] data = new byte[2];
data[0] = 1;
data[1] = 2;

try {
    myAidlInterface.data_inout(data);
    Log.i(TAG, "data_inout method success");
    Log.i(TAG, "after data: " + Arrays.toString(data));
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "data_inout method error: " + e.getMessage());
}
复制代码
data_out input: [1, 2]

data_inout method success
after data: [101, 102]
  1. list_in 方法
java 复制代码
try {
    List<String> list = new ArrayList<>();
    list.add("client item1");
    list.add("client item2");
    myAidlInterface.list_in(list);
    Log.i(TAG, "list_in method success");
    Log.i(TAG, "after list: " + list);
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "list_in method error: " + e.getMessage());
}
复制代码
# Server

list_in input: [client item1, client item2]

# Client

list_in method success
after list: [client item1, client item2]
  1. list_out 方法
java 复制代码
try {
    List<String> list = new ArrayList<>();
    list.add("client item1");
    list.add("client item2");
    myAidlInterface.list_out(list);
    Log.i(TAG, "list_out method success");
    Log.i(TAG, "after list: " + list);
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "list_out method error: " + e.getMessage());
}
复制代码
# Server

list_out input: []

# Client

list_out method success
after list: [server item1, server item2]
  1. list_inout 方法
java 复制代码
try {
    List<String> list = new ArrayList<>();
    list.add("client item1");
    list.add("client item2");
    myAidlInterface.list_inout(list);
    Log.i(TAG, "list_inout method success");
    Log.i(TAG, "after list: " + list);
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "list_inout method error: " + e.getMessage());
}
复制代码
# Server

list_inout input: [client item1, client item2]

# Client

list_inout method success
after list: [client item1, client item2, server item1, server item2]

二、AIDL 传递自定义对象

1、Custom Object
  • Person,这里是位于 src/main/java/com/my/common 包下
java 复制代码
package com.my.common;

import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;

public class Person implements Parcelable {

    public String name;
    public int age;

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

    // 反序列化读取
    protected Person(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    // 序列化写入
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    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];
        }
    };

    // 一般返回 0
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
2、AIDL
  • Person.aidl,这里是位于 src/main/aidl/com/my/common 包下
java 复制代码
package com.my.common;

parcelable Person;
  • MyAidlInterface.aidl,这里是位于 src/main/aidl/com/my/common 包下
java 复制代码
package com.my.common;

import com.my.common.Person;

interface IMyAidlInterface {
    void setPerson(in Person person);
}
3、Server
java 复制代码
private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

    @Override
    public void setPerson(Person person) throws RemoteException {
        Log.i(TAG, "setPerson input: " + person);
    }
};
4、Client Test
java 复制代码
Person person = new Person("client person", 18);

try {
    myAidlInterface.setPerson(person);
    Log.i(TAG, "setPerson method success");
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "setPerson method error: " + e.getMessage());
}
复制代码
# Server

setPerson input: Person{name='client person', age=18}

# Client

setPerson method success

三、AIDL 传递自定义对象(参数方向)

1、Custom Object
  • Person.java
java 复制代码
public class Person implements Parcelable {

    public String name;
    public int age;

    public Person() {
    }

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

    // 反序列化读取
    protected Person(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    // 序列化写入
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    // 从 Parcel 重新读入(用于 out/inout)
    public void readFromParcel(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];
        }
    };

    // 一般返回 0
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
2、AIDL
  • Person.aidl
java 复制代码
package com.my.common;

parcelable Person;
  • MyAidlInterface.aidl
java 复制代码
package com.my.common;

import com.my.common.Person;

interface IMyAidlInterface {
    void person_in(in Person person);
    void person_out(out Person person);
    void person_inout(inout Person person);
}
3、Server
java 复制代码
private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

    @Override
    public void person_in(Person person) throws RemoteException {
        Log.i(TAG, "person_in input: " + person);

        person.name = "server person";
        person.age = 20;
    }

    @Override
    public void person_out(Person person) throws RemoteException {
        Log.i(TAG, "person_out input: " + person);

        person.name = "server person";
        person.age = 20;
    }

    @Override
    public void person_inout(Person person) throws RemoteException {
        Log.i(TAG, "person_inout input: " + person);

        person.name = "server person";
        person.age = 20;
    }
};
4、Client Test
  1. person_in 方法测试
java 复制代码
try {
    Person person = new Person("client person", 18);
    myAidlInterface.person_in(person);
    Log.i(TAG, "person_in method success");
    Log.i(TAG, "after person: " + person);
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "person_in method error: " + e.getMessage());
}
复制代码
# Server

person_in input: Person{name='client person', age=18}

# Client

person_in method success
after person: Person{name='client person', age=18}
  1. person_out 方法测试
java 复制代码
try {
    Person person = new Person("client person", 18);
    myAidlInterface.person_out(person);
    Log.i(TAG, "person_out method success");
    Log.i(TAG, "after person: " + person);
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "person_out method error: " + e.getMessage());
}
复制代码
# Server

person_out input: Person{name='null', age=0}

# Client

person_out method success
after person: Person{name='server person', age=20}
  1. person_inout 方法测试
java 复制代码
try {
    Person person = new Person("client person", 18);
    myAidlInterface.person_inout(person);
    Log.i(TAG, "person_inout method success");
    Log.i(TAG, "after person: " + person);
} catch (RemoteException e) {
    e.printStackTrace();
    Log.e(TAG, "person_inout method error: " + e.getMessage());
}
复制代码
# Server

person_inout input: Person{name='client person', age=18}

# Client

person_inout method success
after person: Person{name='server person', age=20}
相关推荐
杉氧1 小时前
深入理解 Compose 重组机制:快照系统如何驱动 UI 精准刷新?
android·架构·android jetpack
召钱熏1 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端
像我这样帅的人丶你还1 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
杉氧2 小时前
深度解析:Jetpack Compose 核心架构与底层原理 —— 十年安卓老兵的“破茧重生”
android·架构·android jetpack
通玄2 小时前
Jetpack Compose 入门系列(七):ViewModel 与界面状态管理
android
落魄Android在线炒饭2 小时前
Android Framework 开发技巧:android.jar 生成与系统快速编译验证
android
如此风景3 小时前
Kotlin Flow操作符学习
android·kotlin
plainGeekDev3 小时前
GreenDAO → Room
android·java·kotlin
weiggle4 小时前
第八篇:ViewModel + Compose——生产级状态管理实践
android
亦暖筑序8 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端