4. Android基础

说实话,我第一次接触 Android Automotive 时,心里想的是:「这不就是 Android 改了个皮肤吗?」

后来被现实狠狠教育了一顿。它跟手机 Android 的差距,比我想象中大得多。今天我们就来拆开看看,这个专门为汽车而生的系统,到底长什么样。

4.1 Android Automotive OS 架构概览

先看整体架构。我习惯把它分成四层,每层都有它的特殊使命。

Android Automotive OS 四层架构 应用层 (Application Layer) Car Launcher | 车载设置 | 媒体应用 | 电话 | 导航 | 第三方应用 框架层 (Framework Layer) Car Service | Car API | 车辆属性管理 | 驾驶模式 | 音频策略 窗口管理 | 输入管理 | 权限管理 硬件抽象层 (HAL Layer) Vehicle HAL | Audio HAL | Camera HAL | CAN 总线接口 传感器 HAL | 显示 HAL | 网络 HAL 内核层 (Kernel Layer) Linux Kernel | 设备驱动 | 电源管理 | 内存管理 | 进程调度 核心差异:Vehicle HAL 和 Car Service 是手机 Android 没有的组件

这四层里,最值得关注的是框架层和 HAL 层。它们承载了汽车专属的核心逻辑。我当年做第一个项目时,就是低估了 Vehicle HAL 的复杂度,结果在集成阶段吃了大亏。

4.2 与手机 Android 的核心区别

很多人问我:「能不能直接把手机上的 Android 刷到车机上?」

答案是:能跑,但体验会非常糟糕。原因在于几个根本性的差异。

对比维度 手机 Android Android Automotive
启动方式 用户主动开机 上电即启动,要求 5 秒内显示
电源管理 电池供电,深度休眠 车载电源,常电 + 休眠模式
交互方式 触摸为主 触摸 + 旋钮 + 语音 + 方向盘按键
应用模型 单窗口,全屏为主 多窗口,分屏,仪表盘联动
安全要求 用户数据安全 功能安全 (ISO 26262) + 数据安全
生命周期 用户可随意关闭 系统级服务不可关闭

我的经验:最容易被忽视的是「启动时间」。手机开机慢点无所谓,但车机不行。用户上车挂倒挡,如果倒车影像 3 秒还没出来,投诉电话就来了。所以 Automotive 做了大量启动优化,比如提前加载、预创建进程、减少 init 阶段的工作量。

4.3 Car Service:车载系统的中枢神经

Car Service 是 Android Automotive 最核心的系统服务。它负责管理车辆状态、控制硬件、分发事件。

我把它比作「汽车的大脑翻译官」——把车辆 CAN 总线上的信号,翻译成 Android 应用能理解的 API。

4.3.1 Car Service 的主要职责

  • 车辆属性管理:车速、转速、油量、车门状态、空调温度等
  • 驾驶模式管理:停车、行驶、倒车等模式切换
  • 音频策略管理:导航音、媒体音、电话音的路由与混音
  • 车辆控制:空调、车窗、座椅、灯光等控制接口
  • 诊断信息:故障码、传感器数据上报

避坑指南:我曾经在一个项目中,Car Service 的启动顺序没处理好。结果 Car Service 还没注册完成,Launcher 就开始请求车辆速度信息,导致空指针崩溃。解决方案是在 Car Service 的 onBootComplete 回调里加一个「服务就绪」标志位,所有依赖它的应用先等待这个标志位。

4.4 Car API:应用与车辆的桥梁

Car API 是 Google 提供给应用开发者的接口。它封装了 Car Service 的复杂逻辑,让开发者不用关心底层 CAN 协议。

说白了,你写一个导航应用,想获取当前车速,只需要调用 car.getCarPropertyManager().getProperty(VehicleProperty.PERF_VEHICLE_SPEED, 0) 就行。至于这个速度是从 CAN 总线读的,还是从 GPS 算的,你不用管。

4.4.1 核心 API 分类

API 类别 主要接口 典型用途
车辆属性 CarPropertyManager 读取车速、里程、油量
音频管理 CarAudioManager 控制音量、音频焦点
驾驶模式 CarDrivingStateManager 检测车辆行驶状态
车辆控制 CarControlManager 控制空调、车窗
诊断 CarDiagnosticManager 读取故障码

注意:Car API 的调用有权限限制。不是所有应用都能读取车速或控制空调。系统通过 car_user_permission 和 car_manufacturer_permission 两级权限来控制。第三方应用默认只能访问非敏感属性。

4.5 HAL 层适配:连接硬件的关键

HAL 层是 Android Automotive 最「硬核」的部分。它直接跟硬件打交道,把物理信号转换成系统能识别的数据。

我参与的第一个 Automotive 项目,光 Vehicle HAL 的适配就花了两个月。原因很简单——每家车厂的 CAN 协议都不一样。

4.5.1 Vehicle HAL 的核心接口

// Vehicle HAL 的核心接口定义
package android.hardware.automotive.vehicle@2.0;

interface IVehicle {
    // 获取所有支持的车辆属性
    getAllProperties() generates (StatusCode status, vec<VehiclePropConfig> propConfigs);

    // 获取属性值
    get(VehiclePropValue requestedPropValue)
        generates (StatusCode status, VehiclePropValue propValue);

    // 设置属性值
    set(VehiclePropValue propValue) generates (StatusCode status);

    // 订阅属性变化
    subscribe(IVehicleCallback callback, vec<SubscribeOptions> options)
        generates (StatusCode status);

    // 取消订阅
    unsubscribe(IVehicleCallback callback, vec<int32_t> propIds)
        generates (StatusCode status);
}

这个接口看起来简单,但实际适配时坑很多。比如车速这个属性,有的车厂用 km/h,有的用 mph,还有的用脉冲数。你需要在 HAL 层做单位转换。

4.5.2 HAL 适配的典型流程

  1. 分析 CAN 协议:拿到车厂的 CAN 矩阵文档,搞清楚每个信号的含义、范围、精度
  2. 定义属性映射:把 CAN 信号映射到 VehicleProperty 枚举值
  3. 实现 HAL 接口:编写 get/set/subscribe 的具体逻辑
  4. 处理信号转换:做单位换算、数据校验、异常处理
  5. 测试验证:用模拟器 + 实车两种环境验证

我的教训:有一次适配空调控制,CAN 协议上写的是「温度值 = 实际温度 × 10」。我忘了做这个转换,结果应用层设置 25 度,实际空调吹出来的是 250 度。嗯,车里差点变成烤箱。从那以后,我每次做 HAL 适配都会写一个「数据校验层」,在 HAL 内部先验证数值的合理性。

4.6 小结

Android Automotive 不是简单的「手机 Android 改个名」。它从架构、服务、API 到 HAL 层,都做了针对汽车的深度定制。

Car Service 是中枢,Car API 是桥梁,HAL 层是触手。这三者配合,才能让 Android 在车上跑得稳、跑得安全。