1. 创建自定义CarService模块
任务说明
在Android Automotive系统中,CarService是车辆相关功能的核心服务。本案例将实现一个自定义模块:继承CarServiceBase,通过注解注册到CarService中,使其能被系统通过Car管理器正常调用。最终通过编译产物和运行时服务注册日志验证模块已生效。
实现步骤
整个实现分为三个部分:定义AIDL接口、实现继承CarServiceBase的服务类、在CarService中注册该服务。以下代码基于Android 13 (API 33) Automotive源码结构。
1. 定义AIDL接口
创建文件:packages/services/Car/car-lib/src/android/car/ICustomCarService.aidl
package android.car;
interface ICustomCarService {
String getCustomInfo();
void setCustomInfo(String info);
}
2. 实现自定义CarService模块
创建文件:packages/services/Car/service/src/com/android/car/custom/CustomCarService.java
package com.android.car.custom;
import android.car.ICustomCarService;
import android.car.CarLibLog;
import android.car.systeminterface.SystemInterface;
import android.util.Log;
import com.android.car.CarServiceBase;
import com.android.car.CarServiceImpl;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
/**
* 自定义CarService模块示例
* 演示如何继承CarServiceBase并注册到CarService中
*/
public class CustomCarService extends CarServiceBase implements ICustomCarService.Stub {
private static final String TAG = "CustomCarService";
private final CarServiceImpl mCarServiceImpl;
@GuardedBy("this")
private String mCustomInfo = "default_info";
public CustomCarService(CarServiceImpl carServiceImpl) {
mCarServiceImpl = carServiceImpl;
}
@Override
public void init() {
Log.i(TAG, "CustomCarService init");
// 初始化逻辑,例如读取持久化配置
}
@Override
public void release() {
Log.i(TAG, "CustomCarService release");
// 释放资源
}
@Override
public String getCustomInfo() {
synchronized (this) {
return mCustomInfo;
}
}
@Override
public void setCustomInfo(String info) {
Preconditions.checkStringNotEmpty(info, "info cannot be empty");
synchronized (this) {
mCustomInfo = info;
Log.i(TAG, "setCustomInfo: " + info);
}
}
}
3. 注册到CarService
编辑文件:packages/services/Car/service/src/com/android/car/CarServiceImpl.java
在ICarImpl构造函数中注册服务,关键修改如下:
// 在文件顶部import区域添加
import com.android.car.custom.CustomCarService;
// 在ICarImpl类中添加成员变量
private final CustomCarService mCustomCarService;
// 在ICarImpl构造函数中,在现有服务初始化之后添加
mCustomCarService = new CustomCarService(CarServiceImpl.this);
mCustomCarService.init();
registerService(Car.CUSTOM_SERVICE, mCustomCarService);
同时需要在Car.java中定义服务名称常量,编辑packages/services/Car/car-lib/src/android/car/Car.java:
// 在Car类中,与其他SERVICE常量一起添加
public static final String CUSTOM_SERVICE = "custom_car_service";
4. 编译与验证
在Android源码根目录执行以下命令:
source build/envsetup.sh
lunch <your_automotive_target>
m -j32 car-lib car-service
编译成功后,将生成的system.img刷入设备或模拟器。启动后通过adb shell验证:
adb shell dumpsys car_service | grep -A 5 "CustomCarService"
预期输出应包含类似以下内容(示例输出,非实测结果):
CustomCarService:
init called
mCustomInfo: default_info
同时可通过以下命令验证服务可被正常调用:
adb shell cmd car_service call custom_car_service getCustomInfo
若返回default_info,说明服务已成功注册并响应调用。
验证判定标准
- 编译无错误,
car-service包成功生成 - 设备启动后无异常崩溃日志
dumpsys car_service输出中包含CustomCarService且状态为已注册- 通过binder调用
getCustomInfo能返回预期值
常见问题
- 服务未注册:检查
registerService调用是否在init()之后执行,且服务名称与Car.java中定义一致 - 权限异常:确保调用方具有
android.car.permission.CAR_SERVICE权限 - 编译失败:确认AIDL文件已添加到
car-lib的Android.bp或Android.mk的srcs列表中