3. 构建第一个车载应用:从零到一跑起来

说实话,每次带新人入门 Android Automotive,我最怕听到的就是「我照着文档配了,但就是跑不起来」。嗯,这其实不怪你。车载开发和手机开发虽然都是 Android,但坑的姿势完全不同。

这一章,我们就亲手搭一个真正的车载应用。不是 Hello World 那种玩具,而是一个能跑在模拟器上、能响应车载生命周期的正经项目。

3.1 创建 Automotive 项目:别选错模板

打开 Android Studio,点「New Project」。这时候你会看到一堆模板——手机、平板、Wear OS、Android TV……但就是没有「Automotive」这个选项。

别慌。我刚开始也找了半天,后来才发现:车载项目不是选模板,而是选模块

正确姿势:

  1. 新建一个「Empty Activity」的 Android 项目(API 31+)
  2. 在项目里添加一个 automotive 模块
  3. 模块类型选「Phone & Tablet Module」——对,你没看错
  4. 手动修改 build.gradle,加上 Automotive 依赖

为什么这么绕?因为 Google 把 Automotive 当作一个「扩展库」来对待,而不是独立平台。说白了,你的车载应用本质上还是一个 Android 应用,只是多了些车载专属的 API。

// app/build.gradle 关键配置
android {
    compileSdk 34
    defaultConfig {
        minSdk 31  // Automotive 最低要求 Android 12
        targetSdk 34
    }
}

dependencies {
    implementation 'androidx.car.app:app:1.4.0'
    implementation 'androidx.car.app:app-projected:1.4.0'
}

我的习惯:我会把 minSdk 设成 31,因为 Android 12 是 Automotive 的第一个稳定版本。设低了反而容易出兼容性问题。

3.2 AndroidManifest.xml 配置:少一行都不行

车载应用的清单文件和普通应用差别很大。我见过最离谱的错误,就是有人直接把手机应用的清单文件复制过来,结果应用在车机上根本显示不出来。

核心配置有三块,缺一不可:

配置项 说明 我的踩坑记录
<uses-feature> 声明使用车载硬件 少写了这个,应用直接不显示在应用列表
<meta-data> 指定 CarAppService 写错 Service 路径,启动就崩溃
android:required 控制是否强制要求车载功能 设成 true 后,手机调试直接报错
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 声明这是车载应用 -->
    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />

    <application>
        <!-- 车载入口 Service -->
        <service
            android:name=".MyCarAppService"
            android:exported="true">
            <intent-filter>
                <action
                    android:name="androidx.car.app.CarAppService" />
            </intent-filter>
        </service>

        <!-- 指定主 Activity(手机调试用) -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 车载元数据 -->
        <meta-data
            android:name="androidx.car.app.CarAppService"
            android:value=".MyCarAppService" />
    </application>
</manifest>

注意:android:required="true" 意味着这个应用只能在车机上运行。如果你还想在手机上调试,先改成 false。我曾经因为这个配置,在模拟器上折腾了一下午——后来才发现是 required 搞的鬼。

3.3 车载 Activity 生命周期:和手机完全不一样

手机 Activity 的生命周期你肯定熟:onCreate → onStart → onResume → onPause → onStop → onDestroy。

但车载应用不一样。你想想看,开车的时候能像手机那样随便切后台吗?当然不能。所以 Google 专门为车载设计了一套生命周期,叫 CarAppService + Screen

核心区别在于:

  • 手机用 Activity,车载用 CarAppService
  • 手机有 onResume,车载有 onNewIntent
  • 手机可以多实例,车载同一时间只能有一个前台 Screen

来看一个实际的 Service 实现:

public class MyCarAppService extends CarAppService {
    @Override
    public Screen onCreateScreen(Intent intent) {
        // 返回应用的根 Screen
        return new MainScreen(getCarContext());
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化工作,比如日志、统计
    }

    @Override
    public void onDestroy() {
        // 清理资源
        super.onDestroy();
    }
}

而 Screen 的生命周期是这样的:

public class MainScreen extends Screen {
    public MainScreen(CarContext carContext) {
        super(carContext);
    }

    @Override
    public void onCreate() {
        // 创建 UI 和绑定数据
    }

    @Override
    public void onStart() {
        // 开始获取数据、注册监听
    }

    @Override
    public void onResume() {
        // 屏幕可见,开始动画或定时任务
    }

    @Override
    public void onPause() {
        // 屏幕被覆盖,暂停动画
    }

    @Override
    public void onStop() {
        // 完全不可见,释放资源
    }

    @Override
    public void onDestroy() {
        // 彻底销毁
    }
}

关键区别:车载 Screen 没有 onRestart。因为车载场景下,用户不会频繁切回应用。一旦离开,系统可能直接销毁 Screen 来释放内存。

3.4 运行与调试:模拟器才是你的好朋友

没有真车机怎么办?用 Android Automotive 模拟器。Google 在 Android Studio 里直接集成了车载模拟器镜像。

创建模拟器的步骤:

  1. 打开 AVD Manager
  2. 选择「Automotive」分类
  3. 下载 API 34 的 Automotive 镜像(约 2GB)
  4. 启动模拟器——你会看到一个车载中控界面

调试技巧:

  • adb install 安装 APK,模拟器会自动识别为车载应用
  • adb shell dumpsys car_service 查看当前运行的应用
  • 用 Logcat 过滤 CarApp 标签,只看车载相关日志

我曾经踩过的坑:模拟器启动后,应用图标没显示在桌面。后来发现是 uses-featurerequired 设成了 true,但模拟器默认不模拟所有车载硬件。改成 false 就好了。

3.5 本章知识体系:一张图看懂

下面这张图总结了从创建项目到运行调试的完整流程。我建议你把它存下来,以后每次新建车载项目都对照着走一遍。

车载应用创建与运行流程 1. 创建项目 Empty Activity + API 31+ 2. 添加 Automotive 模块 Phone & Tablet 模块 + 手动改配置 3. 配置 AndroidManifest uses-feature + CarAppService 4. 实现 CarAppService onCreateScreen() 返回根 Screen 5. 实现 Screen onCreate → onStart → onResume 6. 运行与调试 模拟器 + adb + Logcat 关键配置清单 ✓ compileSdk 34, minSdk 31 ✓ androidx.car.app:app:1.4.0 ✓ uses-feature: automotive ✓ CarAppService + meta-data

这张图把整个流程分成了 6 个阶段。你按顺序走,每一步都检查一下配置,基本不会出大问题。

3.6 小结

这一章我们走完了车载应用的完整创建流程。从项目模板的选择,到清单文件的配置,再到生命周期和调试方法。说实话,最核心的就三件事:

  • 项目结构:用普通 Android 项目 + Automotive 依赖
  • 清单配置:uses-feature + CarAppService + meta-data,少一个都不行
  • 生命周期:忘掉 Activity,拥抱 CarAppService + Screen

下一章我们会深入 Screen 的 UI 构建,看看怎么用 Template 做出真正的车载界面。不过在那之前,我建议你先把这个项目跑起来——哪怕屏幕上只显示一行字,那也是你第一个能跑的车载应用。


公众号:蓝海资料掘金营,微信 deep3321