You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Stable AIDL定义带Parcelable的自定义类?

基于Stable AIDL实现Java与C++跨语言交互方案

Stable AIDL要求所有Parcelable必须是结构化类型——即必须在AIDL文件中显式声明所有字段,不能再通过旧AIDL的cpp_header指令关联自定义C++头文件实现自定义序列化逻辑。以下是适配Stable AIDL的跨语言交互实现方案:

1. 定义结构化Parcelable与AIDL接口

首先在AIDL中定义需要跨语言传递的Parcelable对象和服务接口,所有字段必须显式声明,并添加@Stable注解(适用于Android 12及以上版本):

定义Parcelable对象

// Person.aidl
package com.example;

@Stable
parcelable Person {
    String name;
    int age;
    boolean isAdult;
}

定义跨语言服务接口

// IMyService.aidl
package com.example;

import com.example.Person;

@Stable
interface IMyService {
    void sendPerson(in Person person);
    Person getPerson();
}

2. 自动生成跨语言绑定代码

编译AIDL文件后,构建系统会自动生成:

  • Java端:包含序列化逻辑的Person类,以及IMyService的Stub/Proxy实现
  • C++端:继承自android::Parcelable的Person类,以及IMyService的Bn/Bp代理类

无需手动编写C头文件,Stable AIDL生成的代码会保证Java和C端序列化逻辑完全一致。

3. C++端实现服务逻辑

基于自动生成的代码,实现服务的具体逻辑:

#include "com/example/IMyService.h"
#include "com/example/Person.h"
#include <android/log.h>

using namespace android;
using namespace com::example;

#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "MyService", __VA_ARGS__)

class MyService : public BnMyService {
public:
    binder::Status sendPerson(const Person& person) override {
        // 处理从Java端传递来的Person对象
        ALOGD("Received Person: name=%s, age=%d, isAdult=%d",
              person.name().c_str(), person.age(), person.isAdult());
        return binder::Status::ok();
    }

    binder::Status getPerson(Person* _return) override {
        // 创建Person对象返回给Java端
        _return->set_name("Alice");
        _return->set_age(25);
        _return->set_isAdult(true);
        return binder::Status::ok();
    }
};

int main() {
    // 将服务注册到系统ServiceManager
    defaultServiceManager()->addService(String16("my.service"), new MyService());
    IPCThreadState::self()->joinThreadPool();
    return 0;
}

4. Java端绑定并调用C++服务

在Java代码中绑定远程服务,调用接口传递或获取Parcelable对象:

package com.example;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private IMyService myService;

    private final ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myService = IMyService.Stub.asInterface(service);
            try {
                // 向C++服务发送Person对象
                Person person = new Person();
                person.setName("Bob");
                person.setAge(30);
                person.setIsAdult(true);
                myService.sendPerson(person);

                // 从C++服务获取Person对象
                Person receivedPerson = myService.getPerson();
                Log.d(TAG, "Received Person: name=" + receivedPerson.getName()
                        + ", age=" + receivedPerson.getAge()
                        + ", isAdult=" + receivedPerson.getIsAdult());
            } catch (RemoteException e) {
                Log.e(TAG, "Remote call failed", e);
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            myService = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 绑定C++远程服务
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.example", "com.example.MyService"));
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }
}

核心注意事项

  • 所有跨语言传递的Parcelable必须在AIDL中完整定义字段,Stable AIDL会自动处理序列化/反序列化,无需手动实现相关方法
  • 务必为AIDL文件添加@Stable注解,确保接口跨Android版本的兼容性
  • 编译时需正确配置AIDL路径,确保构建系统生成对应的Java和C++绑定代码

内容的提问来源于stack exchange,提问作者wic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 23:37:43