android hal aidl升级部分-android framework车载手机系统开发

背景:

第一版本的aidl没有指定版本,只有一个aidl_api下面current文件夹即默认就是版本v1,那么如果后面有相关的接口修改呢?
那么应该怎么办,怎么操作?

修改aidl

在修改接口前记得把老版本的aidl进行冻结一下
冻结命令:
m android.hardware.mytest-freeze-api
执行后相关的aidl_api目录多个一个版本目录
在这里插入图片描述

可以看到这里的版本多了版本1,而且还带有hash号文件

接下来既可以修改aidl文件了

package android.hardware.mytest; 
import android.hardware.mytest.MyTestObj; 
@VintfStability 
interface IMyTest {
    MyTestObj test();
    void addTest(int a,int b); //增加了一个接口方法
}



注意这里修改aidl接口也不是随意修改的哈,官方有相关要求:

In addition, you need to manage ToT version's API definition. Whenever an API is updated, run foo-update-api to update aidl_api/name/current which contains ToT version's API definition.

To maintain the stability of an interface, owners can add new:

Methods to the end of an interface (or methods with explicitly defined new serials)
Elements to the end of a parcelable (requires a default to be added for each element)
Constant values
In Android 11, enumerators
In Android 12, fields to the end of a union
No other actions are permitted, and no one else can modify an interface (otherwise they risk collision with changes that an owner makes).

大概就是修改时候一定要考虑老版本的兼容问题,一般不删除原来接口和修改
然后执行命令:

m android.hardware.mytest-update-api

可以看到out临时文件目录多了V2相关的库

test@test:~/nx563j_xiaomi/out/soong/.intermediates/hardware/interfaces/mytest/aidl$ ll
total 40
drwxrwxr-x 10 test test 4096 Dec 13 20:57 ./
drwxrwxr-x  3 test test 4096 Dec 13 20:57 ../
drwxrwxr-x  4 test test 4096 Dec 13 20:57 android.hardware.mytest-V1-ndk/
drwxrwxr-x  3 test test 4096 Dec 13 20:57 android.hardware.mytest-V1-ndk-source/
drwxrwxr-x  4 test test 4096 Dec 13 20:57 android.hardware.mytest-V2-ndk/
drwxrwxr-x  3 test test 4096 Dec 13 20:57 android.hardware.mytest-V2-ndk-source/

修改实现代码的和android.bp

MyTestImpl.h增加相关方法引入

class MyTestImpl : public BnMyTest {
  public:
    ::aidl::android::hardware::mytest::MyTestObj  mObj = {"hello",1};
    ::ndk::ScopedAStatus test(::aidl::android::hardware::mytest::MyTestObj* _aidl_return) override;
    ::ndk::ScopedAStatus addTest(int32_t in_a, int32_t in_b) override;

};

MyTestImpl.cpp增加相关方法实现


namespace aidl::android::hardware::mytest {
    
::ndk::ScopedAStatus MyTestImpl::test(::aidl::android::hardware::mytest::MyTestObj* _aidl_return) {
        *_aidl_return = mObj;
        ALOGE(" MyTestImpl::test ok");
        return ::ndk::ScopedAStatus::ok();
}
  ::ndk::ScopedAStatus  MyTestImpl::addTest(int32_t in_a, int32_t in_b) {
        ALOGE(" MyTestImpl::test ok a %d  b %d",in_a,in_b);
        return ::ndk::ScopedAStatus::ok();
  }


}  // namespace aidl::android::hardware::mytest

Android.bp需要把原来V1版本的库变成V2
在这里插入图片描述
更多framework干货请关注“千里马学框架”

07-10
### AIDL 使用指南 #### 1. **AIDL 的基本概念** Android 接口定义语言(AIDL)是一种接口描述语言,用于在 Android 应用之间进行跨进程通信(IPC)。它允许一个应用通过 Binder 机制调用另一个应用中的服务方法。这种机制基于代理模式实现,使得客户端和服务端能够通过接口进行交互[^2]。 #### 2. **AIDL 的优势** 与其他 IPC 方式相比,例如广播、共享文件或 `ContentProvider`,AIDL 提供了更高的效率和更好的用户体验: - **高效性**:AIDL 直接使用 Binder 进行通信,相较于使用 Intent 或广播传递复杂对象,具有更高的性能。 - **异步支持**:AIDL 支持异步调用,服务端可以通过回调机制响应客户端请求。 - **类型安全**:AIDL 支持多种数据类型(包括复杂结构),编译器会在编译时检查数据类型以确保安全性。 - **易于维护**:AIDL 接口定义清晰,便于后续的维护和扩展[^3]。 #### 3. **AIDL 接口的定义与实现** ##### 定义 AIDL 接口 首先,在 Android 项目中创建 `.aidl` 文件来定义接口。例如,假设需要定义一个简单的远程服务接口 `IMyAidlInterface.aidl`: ```aidl // IMyAidlInterface.aidl package com.example.myapp; interface IMyAidlInterface { int add(int a, int b); } ``` 该接口定义了一个名为 `add` 的方法,接受两个整数参数并返回它们的和。 ##### 实现服务端逻辑 接下来,在服务端应用中创建一个 `Service` 类,并实现上述接口: ```java public class MyAidlService extends Service { private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() { @Override public int add(int a, int b) throws RemoteException { return a + b; } }; @Override public IBinder onBind(Intent intent) { return binder; } } ``` 同时,需要在 `AndroidManifest.xml` 中注册此服务,并声明适当的权限以允许外部访问: ```xml <service android:name=".MyAidlService" android:exported="true"> <intent-filter> <action android:name="com.example.myapp.IMyAidlInterface"/> </intent-filter> </service> ``` ##### 客户端绑定服务 客户端通过绑定到服务的方式获取接口实例,并调用远程方法: ```java private IMyAidlInterface myAidlInterface; private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { myAidlInterface = IMyAidlInterface.Stub.asInterface(service); try { int result = myAidlInterface.add(5, 7); Log.d("AIDL", "Result: " + result); } catch (RemoteException e) { Log.e("AIDL", "Remote call failed", e); } } @Override public void onServiceDisconnected(ComponentName name) { myAidlInterface = null; } }; Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.myapp", "com.example.myapp.MyAidlService")); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); ``` #### 4. **常见问题与解决方案** ##### 问题 1: `RemoteException` 异常处理 当客户端尝试调用远程服务的方法时,可能会抛出 `RemoteException`。这是由于 IPC 通信失败导致的,例如服务未启动或 Binder 被断开连接。 **解决方案**: - 在调用 AIDL 方法时使用 `try-catch` 捕获异常。 - 确保服务已正确启动并在客户端成功绑定后才调用方法。 ```java try { int result = myAidlInterface.add(5, 7); } catch (RemoteException e) { Log.e("AIDL", "Remote call failed", e); } ``` ##### 问题 2: 权限不足 (`SecurityException`) 如果客户端没有足够的权限访问服务,会抛出 `SecurityException`。 **解决方案**: - 在服务端的 `AndroidManifest.xml` 中配置正确的权限。 - 客户端申请必要的权限(如 `uses-permission`)。 ```java try { int result = myAidlInterface.add(5, 7); } catch (SecurityException e) { Log.e("AIDL", "Permission denied", e); } ``` ##### 问题 3: 大对象传输效率低下 AIDL 不适合传输大对象(如大型图片或视频)。这是因为每次传输都需要序列化和反序列化,这可能导致性能下降。 **解决方案**: - 避免使用 `inout` 关键字传递大对象。 - 对于大数据传输,建议使用其他方式,如 `ContentProvider` 或 `Socket` 通信。 ##### 问题 4: 线程安全问题 AIDL 调用默认运行在 Binder 线程池中,因此需要注意线程安全问题。 **解决方案**: - 如果服务端方法涉及共享资源操作,应使用同步机制(如 `synchronized`)保护关键代码段。 - 避免在 AIDL 方法中执行耗时操作,以免阻塞 Binder 线程。 #### 5. **最佳实践** - **接口设计简洁**:保持 AIDL 接口简单明了,避免过于复杂的逻辑。 - **版本控制**:随着功能迭代,注意接口版本管理,确保兼容性。 - **日志记录**:在关键位置添加日志输出,方便调试和排查问题。 - **测试验证**:编写单元测试验证 AIDL 接口的功能和稳定性。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值