别再乱学了!深度解读 Google 官方发布 Android 6 大核心 Skills

一、为什么 Google 要做这件事?

背景

AI 编程工具井喷式爆发:Cursor、Claude Code等,开发者用自然语言就能写代码。

但有个致命问题:AI 不懂 Android 的"潜规则",会出现一些很痛苦的场景:

  • 你让它帮你升级 AGP 版本,它可能改了 build.gradle 却忘了清 gradle.properties 里的废弃 flag;
  • 你让它迁移 XML 到 Compose,它可能顺手把你的业务逻辑也重构了------你没让它改的地方,它改了。

根本原因

通用 LLM 的训练数据是互联网上的"平均水平",而不是 Google 官方当下推荐的最佳实践。版本一更新,老文档就变成了误导。

所以 Google 做了一个决定:

🎯 把官方专家知识打包成结构化指令(SKILL.md),直接注入 AI 的上下文窗口,让 AI Agent 按官方标准执行任务。

这就是 android/skills 的本质------不是给人看的文档,是写给 AI 的"操作手册"

与社区方案的本质区别

维度 社区方案(博客/教程) android/skills
受众 人类开发者 AI Agent
格式 自然语言文章 结构化 SKILL.md + 参考资料
维护者 个人/社区 Google 官方团队
时效性 依赖作者更新 CI/CD 自动同步最新实践
执行方式 人工理解后手动操作 AI 读取后自动执行代码修改
规范标准 无统一标准 遵循 Agent Skills 开放标准

总结

  • 社区方案:教你"怎么做"
  • android/skills让 AI 替你做,还做对

二、具体包含哪些内容?

目前 android/skills 仓库(v0.0.2)包含 6 个官方 Skill ,覆盖 Android 开发中最高频、最容易出错的 6 个工程场景:

# Skill 名称 所属领域 具体作用
1 AGP 9 Upgrade 构建 把 AGP 升级到 9.0 的全流程自动化
2 Migrate to Compose UI 把 XML 布局安全地迁移到 Jetpack Compose
3 Navigation 3 架构 在应用中正确集成 Navigation 3 新框架
4 R8 Analyzer 性能 审计 R8/ProGuard 配置,找出冗余 keep 规则
5 Play Billing Upgrade 商业化 跨大版本升级 Play 计费库
6 Edge-to-Edge 系统 Android 15 强制全面屏适配

⚠️ 注意:这 6 个 Skill 之间不是线性递进关系 ,而是按需加载、独立执行的。AI Agent 会根据你的自然语言请求自动匹配最相关的 Skill。

仓库目录结构一览

bash 复制代码
android/skills/
├── build/agp/agp-9-upgrade/           # Skill 1: AGP 升级
│   ├── SKILL.md
│   └── references/
├── jetpack-compose/migration/          # Skill 2: Compose 迁移
│   └── migrate-xml-views-to-jetpack-compose/
│       ├── SKILL.md
│       └── references/
├── navigation/navigation-3/            # Skill 3: Navigation 3
│   ├── SKILL.md
│   └── references/
├── performance/r8-analyzer/            # Skill 4: R8 分析
│   ├── SKILL.md
│   └── references/
├── play/play-billing-library-version-upgrade/  # Skill 5: 计费升级
│   ├── SKILL.md
│   └── references/
└── system/edge-to-edge/                # Skill 6: 全面屏适配
    ├── SKILL.md
    └── references/

⚠️ 注意:每个 Skill 的核心就是一个 SKILL.md 文件------YAML 元数据头 + Markdown 格式的结构化指令,配合 references/ 目录下的深度技术参考文档。

下面,我将为你逐一硬核拆解6 大 Skills


🔧 Skill 1:AGP 9 Upgrade ------ 构建系统的破坏性升级

📌 作用

将 Android Gradle Plugin 从旧版本安全升级到 AGP 9 的全流程自动化指令集。

📖 具体描述

AGP 9 是一次破坏性大版本升级(Breaking Change) ,涉及 Kotlin 编译器集成方式、Gradle DSL 语法、注解处理器框架等核心变更。手动升级极易遗漏步骤,而这正是 AI Skill 最擅长的场景------把复杂流程结构化,逐步执行,逐步验证

🔑 核心知识点拆解

1. Built-in Kotlin 迁移

AGP 9 内置了 Kotlin 编译器插件,不再需要独立声明 kotlin-android 插件版本。这意味着:

  • 移除 build.gradle 中独立的 Kotlin 版本声明
  • AGP 版本直接决定了 Kotlin 版本
  • 减少版本冲突,但升级时需要确认 Kotlin 兼容性

2. 新 AGP DSL 迁移

旧版 DSL 中许多 API 已废弃或移除,常见变更包括:

  • android.buildFeatures 内的配置项调整
  • testOptionspackaging 等 Block 的 API 重命名
  • Variant API 的全面重构

3. kapt → KSP 迁移

KSP(Kotlin Symbol Processing)是 kapt 的替代方案,编译速度提升 2x+:

  • 要求 KSP 版本 ≥ 2.3.6
  • 对于暂不支持 KSP 的库,可临时使用 legacy-kapt
  • Dagger/Hilt、Room 等主流库均已支持 KSP

4. gradle.properties 清理

AGP 9 移除了多个历史遗留 flag(如 android.useAndroidXandroid.enableJetifier 等),不清理会导致构建警告或失败。

5. 三重验证机制

bash 复制代码
Gradle Sync 成功 → ./gradlew help 通过 → ./gradlew build --dry-run 通过

💻 实战代码:AGP 9 的 build.gradle.kts 变更

kotlin 复制代码
// ❌ AGP 8.x 旧写法
plugins {
    id("com.android.application") version "8.5.0"
    id("org.jetbrains.kotlin.android") version "2.0.0"  // 独立声明 Kotlin 版本
    id("kotlin-kapt")  // 使用 kapt
}

// ✅ AGP 9.x 新写法
plugins {
    id("com.android.application") version "9.0.0"
    // Kotlin 版本由 AGP 内置管理,无需单独声明
    id("com.google.devtools.ksp") version "2.3.6-1.0.0"  // kapt → KSP
}

android {
    namespace = "com.example.app"
    compileSdk = 35

    // AGP 9 新 DSL
    buildFeatures {
        compose = true
        // buildConfig = true  // 自定义 BuildConfig 需显式开启
    }
}

⚠️ 常见踩坑点

  1. 直接改版本号而不跑 Upgrade Assistant :AGP 9 的变更太多,手动改版本号几乎必然遗漏。正确做法是先在 Android Studio 中运行 Tools > AGP Upgrade Assistant,让工具处理自动化部分,再处理手动项。

  2. 忽略 gradle.properties 清理 :很多项目的 gradle.properties 里堆积了多年的 flag,如 android.enableJetifier=true。AGP 9 不再识别这些 flag,不清理会导致诡异的构建失败。


🎨 Skill 2:Migrate XML Views to Jetpack Compose

这是最值得关注的迁移技能

📌 作用

将基于 XML View 的界面安全、渐进地迁移到 Jetpack Compose 的 10 步方法论。

📖 具体描述

这是 6 个 Skill 中指令最长、约束最严格的一个。Google 很清楚:Compose 迁移是当前 Android 社区最大规模的"集体搬家",也是最容易搞砸的。

这个 Skill 的核心约束只有一条:

🔒 只迁移 UI,不改业务逻辑。保持原有代码风格一致。

这条约束至关重要。很多开发者(包括 AI)在迁移 Compose 时,会"顺手"重构 ViewModel、改数据流、优化架构------结果迁移变成了重写,风险指数级上升。

🔑 核心知识点拆解

1. 候选布局自动筛选

Skill 会指导 AI 分析项目中所有 XML 布局文件,按照以下维度排序候选迁移对象:

  • 布局复杂度(嵌套层级越深,迁移收益越大)
  • 依赖关系(独立组件优先于深度耦合组件)
  • 使用频率(高频页面优先验证 Compose 性能)

2. XML → Compose 映射规则

XML 组件 Compose 等价物 注意事项
LinearLayout (vertical) Column 注意 weightModifier.weight()
LinearLayout (horizontal) Row ---
ConstraintLayout ConstraintLayout(Compose 版) 需要独立依赖 constraintlayout-compose
RecyclerView LazyColumn / LazyRow 性能模型完全不同,需关注 key
TextView Text SpannableStringAnnotatedString
ImageView Image / AsyncImage(Coil) 推荐使用 Coil 3.x
Fragment NavHost + Composable 结合 Navigation 3 使用

3. ComposeView 桥接策略

迁移期间,新旧 UI 会共存。桥接方式:

kotlin 复制代码
// 在现有 Fragment/Activity 中嵌入 Compose
class LegacyFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setViewCompositionStrategy(
                ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
            )
            setContent {
                AppTheme {
                    // 新的 Compose UI
                    NewFeatureScreen(
                        viewModel = viewModel()
                    )
                }
            }
        }
    }
}

4. 最小主题配置

迁移初期不需要完整的 Material3 主题,只需一个最小 Theme Wrapper:

kotlin 复制代码
@Composable
fun AppTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colorScheme = dynamicColorScheme(LocalContext.current)
            ?: lightColorScheme(),
        typography = Typography(),  // 后续逐步自定义
        content = content
    )
}

5. UI 截图对比验证

迁移完成后,Skill 要求对比迁移前后的 UI 截图,确保视觉一致性。这是很多人忽略的一步------"能编译通过"不等于"UI 没变"。

💻 实战代码:一个典型的 XML → Compose 迁移

kotlin 复制代码
// 迁移前:item_user.xml 中的 CardView 列表项
// <CardView>
//   <LinearLayout orientation="horizontal">
//     <ImageView android:id="@+id/avatar" />
//     <LinearLayout orientation="vertical">
//       <TextView android:id="@+id/name" />
//       <TextView android:id="@+id/email" />
//     </LinearLayout>
//   </LinearLayout>
// </CardView>

// ✅ 迁移后:等价的 Compose 组件
@Composable
fun UserListItem(
    user: User,
    modifier: Modifier = Modifier
) {
    Card(
        modifier = modifier.fillMaxWidth(),
        shape = RoundedCornerShape(12.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
    ) {
        Row(
            modifier = Modifier.padding(16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            AsyncImage(
                model = user.avatarUrl,
                contentDescription = "Avatar",
                modifier = Modifier
                    .size(48.dp)
                    .clip(CircleShape),
                contentScale = ContentScale.Crop
            )
            Spacer(modifier = Modifier.width(12.dp))
            Column {
                Text(
                    text = user.name,
                    style = MaterialTheme.typography.titleMedium
                )
                Text(
                    text = user.email,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        }
    }
}

📦 依赖坐标

  • androidx.compose.material3:material3:1.4.0
  • io.coil-kt.coil3:coil-compose:3.1.0

⚠️ 常见踩坑点

  1. setContent 中直接引用 Activity 的成员变量 :Compose 的重组(Recomposition)机制意味着 setContent 内的代码可能被多次执行。直接引用 Activity 字段可能导致状态不一致。正确做法是通过 ViewModel + State 管理数据。

  2. 迁移时混改业务逻辑:这是 Skill 反复强调的红线。迁移 Compose 时只改 UI 层代码,ViewModel、Repository、数据源一行都不要动。混改 = 无法定位 Bug 源头。


🧭 Skill 3:Navigation 3

这是下一代导航框架

📌 功能

使用 Navigation 3(状态驱动的全新导航框架)在应用中实现路由、Deep Link 和自适应布局的完整指南。

📖 具体描述

Navigation 3 是对 Navigation 2 的范式级重构,核心理念从"命令式导航"转向"状态驱动导航":

  • Navigation 2:navController.navigate("detail/$id") → 命令式,告诉框架"去哪里"
  • Navigation 3:通过修改 Back Stack 状态来驱动导航 → 声明式,描述"当前状态是什么"

这与 Jetpack Compose 的声明式理念完全一致。

🔑 核心知识点拆解

1. entryProvider DSL ------ 路由声明新范式

Navigation 3 引入了 entryProvider DSL 来声明路由,替代 Navigation 2 的 NavGraph

kotlin 复制代码
@Composable
fun AppNavHost() {
    val backStack = rememberNavBackStack(startDestination = HomeRoute)

    NavDisplay(
        backStack = backStack,
        entryProvider = entryProvider {
            entry<HomeRoute> { route ->
                HomeScreen(
                    onNavigateToDetail = { id ->
                        backStack.add(DetailRoute(id))
                    }
                )
            }

            entry<DetailRoute> { route ->
                DetailScreen(
                    itemId = route.id,
                    onBack = { backStack.removeLastOrNull() }
                )
            }
        }
    )
}

// 类型安全的路由定义
@Serializable
data object HomeRoute

@Serializable
data class DetailRoute(val id: String)

2. 可持久化 Back Stack

Navigation 3 的 Back Stack 天然支持持久化------应用被系统杀死后恢复时,导航栈自动恢复。这在 Navigation 2 中需要额外配置。

3. 多 Back Stack(底部导航)

底部导航 + 多 Tab 各自维护独立 Back Stack 是 Navigation 2 的经典难题。Navigation 3 通过状态驱动原生支持:

kotlin 复制代码
@Composable
fun MainScreen() {
    val tabs = listOf(HomeRoute, SearchRoute, ProfileRoute)
    var selectedTab by remember { mutableIntStateOf(0) }

    Scaffold(
        bottomBar = {
            NavigationBar {
                tabs.forEachIndexed { index, route ->
                    NavigationBarItem(
                        selected = selectedTab == index,
                        onClick = { selectedTab = index },
                        icon = { Icon(route.icon, contentDescription = null) },
                        label = { Text(route.label) }
                    )
                }
            }
        }
    ) { padding ->
        // 每个 Tab 独立维护自己的 back stack
        NavDisplay(
            backStack = rememberNavBackStack(
                key = tabs[selectedTab],
                startDestination = tabs[selectedTab]
            ),
            modifier = Modifier.padding(padding),
            entryProvider = entryProvider { /* ... */ }
        )
    }
}

4. Deep Link 与合成 Back Stack

Navigation 3 支持 URL 解析并自动合成完整的 Back Stack:

kotlin 复制代码
// 用户通过 deep link 直接打开 detail 页面
// Navigation 3 自动合成:[HomeRoute, DetailRoute(id)] 的 back stack
// 按返回键会正确回到 Home 而不是退出应用

5. 自适应布局(List-Detail)

结合 Material Adaptive 库,Navigation 3 原生支持大屏设备的 List-Detail 双栏布局:

kotlin 复制代码
// 手机:列表页 → 点击 → 详情页(全屏)
// 平板/折叠屏:左侧列表 + 右侧详情(双栏并排)
// Navigation 3 根据窗口尺寸自动切换,无需手动判断

⚠️ 常见踩坑点

  1. 用 Navigation 2 的思维写 Navigation 3 :最典型的错误是还在用 navigate() 式的命令式 API。Navigation 3 的核心是操作 Back Stack 状态(add / removeLastOrNull),不是发"导航指令"。

  2. 忽略类型安全路由 :Navigation 3 推荐使用 @Serializable 数据类定义路由,而不是字符串。字符串路由容易拼写错误且缺乏编译期检查。


⚡ Skill 4:R8 Analyzer

这是APK 瘦身的精准手术刀

📌 作用

审计项目的 R8/ProGuard keep 规则,找出冗余配置,输出优化建议------但只建议,不动手

📖 具体描述

这是 6 个 Skill 中最保守的一个。R8 规则直接影响 APK 的代码缩减和混淆,改错一条规则就可能导致线上 Crash。所以 Google 给这个 Skill 定了一条铁律:

🔒 绝不直接修改 keep 规则文件,只做分析和建议。

这个设计哲学很值得品味:AI 的边界不是"能不能做",而是"该不该做"。

🔑 核心知识点拆解

1. R8 是什么?

R8 是 Android 官方的代码缩减器(Code Shrinker),集成在 AGP 中,负责:

  • 代码缩减(Tree Shaking):移除未使用的类和方法
  • 代码混淆(Obfuscation):缩短类名、方法名
  • 代码优化(Optimization):内联、常量折叠等

2. keep 规则的"技术债"

大多数项目的 proguard-rules.pro 文件都是这样的:

php 复制代码
# 某个同事 3 年前加的,没人敢删
-keep class com.example.legacy.** { *; }

# Stack Overflow 抄来的,不确定还需不需要
-keepclassmembers class * implements java.io.Serializable { *; }

# 第三方 SDK 要求的,但 SDK 已经自带 consumer rules 了
-keep class com.thirdparty.sdk.** { *; }

这些冗余规则导致 R8 无法充分优化,APK 体积白白增大。

3. 分析维度

R8 Analyzer Skill 从 5 个维度审计:

  • 冗余规则:第三方库已自带 consumer rules,项目中再声明是多余的
  • 过宽规则-keep class ** 这种"全保留"规则直接废掉了 R8
  • 互相包含:规则 A 已经覆盖了规则 B 的范围
  • 反射相关:分析反射调用,建议更精确的 keep 规则
  • 影响排序:按对 APK 体积的潜在影响从大到小排列

💻 实战代码:R8 配置最佳实践

kotlin 复制代码
// build.gradle.kts
android {
    buildTypes {
        release {
            isMinifyEnabled = true   // 开启代码缩减
            isShrinkResources = true // 开启资源缩减
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

// proguard-rules.pro ------ 精简后的规则示例
# 只保留确实需要的反射类
-keep class com.example.app.model.** { *; }

# 枚举类序列化
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# 不要保留行号(进一步缩减)但保留源文件名(方便 Crash 定位)
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile

⚠️ 常见踩坑点

  1. 删除 keep 规则后只跑了单元测试就上线 :R8 相关的 Bug 往往只在 Release 包中出现(Debug 包不做混淆),且很多是运行时反射失败。正确做法是:改完规则后用 UI Automator 做全流程 E2E 测试,覆盖核心业务路径。

  2. 把 consumer rules 当成"项目级规则" :第三方 AAR 自带的 consumer rules 会自动合并到最终的 R8 配置中,不需要在项目的 proguard-rules.pro 中重复声明。


💳 Skill 5:Play Billing Library Upgrade

📌 功能

跨大版本安全升级 Google Play 计费库,确保应用内购买/订阅功能不中断。

📖 具体描述

支付模块是所有模块中容错率最低的------一个 Bug 就可能导致用户付了钱收不到商品,或者订阅续费失败。所以这个 Skill 的设计极其谨慎,有几个关键决策:

  • 跨度 >2 个大版本时分步跳:例如从 PBL v4 到 v8,不会直接跳,而是 v4 → v6 → v8,每步验证
  • 基于代码意图重构,非简单字符串替换 :不是 SkuDetails 全局替换成 ProductDetails,而是理解你的业务逻辑后做语义级重构
  • 判定旧版本的方式 :如果代码中使用了 SkuDetails(已在 PBL 5+ 废弃),则判定为 PBL 4 或更早

🔑 核心知识点拆解

1. PBL 版本变迁核心变更

版本 核心变更 影响
PBL 5 SkuDetailsProductDetails 商品查询 API 全面重构
PBL 6 引入 PurchasesUpdatedListener 新回调 购买流程重构
PBL 7 订阅模型重构(BasePlan + Offer) 订阅价格管理全面变更
PBL 8 Kotlin-first API,协程原生支持 异步调用方式变更

2. 迁移路径计算

makefile 复制代码
当前版本: PBL 4
目标版本: PBL 8

计算出的迁移路径:
  Step 1: PBL 4 → PBL 6 (编译验证 ✓)
  Step 2: PBL 6 → PBL 8 (编译验证 ✓)

3. 关键 API 变更示例

kotlin 复制代码
// ❌ PBL 4 旧 API
val params = SkuDetailsParams.newBuilder()
    .setSkusList(listOf("premium_monthly"))
    .setType(BillingClient.SkuType.SUBS)
    .build()
billingClient.querySkuDetailsAsync(params) { result, skuDetailsList ->
    // ...
}

// ✅ PBL 7+ 新 API
val params = QueryProductDetailsParams.newBuilder()
    .addProduct(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("premium_monthly")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )
    .build()

// Kotlin 协程版本(PBL 8+)
val result = billingClient.queryProductDetails(params)
result.productDetailsList?.forEach { productDetails ->
    // 处理商品详情
    val offers = productDetails.subscriptionOfferDetails
    // ...
}

📦 依赖坐标com.android.billingclient:billing-ktx:7.1.1(截至 2026 年 4 月最新稳定版)

⚠️ 常见踩坑点

  1. 只改客户端不改服务端:PBL 7+ 的订阅模型从单一 SKU 变成了 BasePlan + Offer 结构,服务端的购买验证逻辑也需要同步更新。只改客户端会导致服务端解析购买 Token 失败。

  2. 忽略 Google Play Console 的配置迁移:新版 PBL 要求在 Play Console 中为订阅商品配置 BasePlan 和 Offer,否则客户端查询不到商品。


📱 Skill 6:Edge-to-Edge

这是 Android 15 的强制毕业考

📌 功能

为 Compose 应用实现 Edge-to-Edge(全面屏/无边框)适配,应对 Android 15(SDK 35)的强制要求。

📖 具体描述

Android 15(SDK 35) 开始,系统强制启用 Edge-to-Edge 模式 ------无论你适配与否,应用都会被全面屏渲染。这意味着:如果你不主动处理 Window Insets,你的内容一定会被系统栏遮挡

这不是"建议适配",是"不适配就出 Bug"。

🔑 核心知识点拆解

1. enableEdgeToEdge() 一行代码启用

kotlin 复制代码
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()  // ← 这一行,放在 super.onCreate() 之前
        super.onCreate(savedInstanceState)
        setContent {
            AppTheme {
                AppContent()
            }
        }
    }
}

📦 依赖坐标androidx.activity:activity-compose:1.10.0enableEdgeToEdge 来自这个库)

2. Window Insets 处理------最核心的适配工作

Edge-to-Edge 的难点不在开启,在于正确处理 Insets(系统栏占用的区域):

kotlin 复制代码
@Composable
fun AppContent() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("My App") },
                // TopAppBar 自动处理状态栏 Insets ✅
            )
        },
        bottomBar = {
            NavigationBar {
                // NavigationBar 自动处理导航栏 Insets ✅
            }
        }
    ) { innerPadding ->
        // ⚠️ 关键:使用 Scaffold 提供的 innerPadding
        LazyColumn(
            contentPadding = innerPadding  // ← 列表内容不被遮挡
        ) {
            items(100) { index ->
                ListItem(headlineContent = { Text("Item $index") })
            }
        }
    }
}

3. IME(输入法)适配------最容易出错的场景

kotlin 复制代码
// ❌ 错误:双重 padding
TextField(
    modifier = Modifier
        .imePadding()           // padding 1
        .navigationBarsPadding() // padding 2 ← 键盘弹起时导航栏已被键盘覆盖
)

// ✅ 正确:只用 imePadding()
TextField(
    modifier = Modifier
        .imePadding()  // 自动包含了导航栏的处理
)

4. FAB 与列表的配合

当页面底部有 FloatingActionButton 时,列表最后一个 item 可能被 FAB 挡住:

kotlin 复制代码
Scaffold(
    floatingActionButton = {
        FloatingActionButton(onClick = { /* ... */ }) {
            Icon(Icons.Default.Add, contentDescription = "Add")
        }
    }
) { innerPadding ->
    LazyColumn(
        contentPadding = innerPadding  // Scaffold 的 innerPadding 已经考虑了 FAB
    ) {
        // 列表内容
    }
}

5. 全屏 Dialog 的 Edge-to-Edge

Dialog 默认不会继承宿主 Activity 的 Edge-to-Edge 设置,需要单独处理:

kotlin 复制代码
Dialog(
    onDismissRequest = { /* ... */ },
    properties = DialogProperties(
        usePlatformDefaultWidth = false,
        decorFitsSystemWindows = false  // ← 关键:让 Dialog 也 Edge-to-Edge
    )
) {
    Surface(
        modifier = Modifier
            .fillMaxSize()
            .windowInsetsPadding(WindowInsets.systemBars)
    ) {
        // Dialog 内容
    }
}

⚠️ 常见踩坑点

  1. Scaffold padding 和手动 Insets padding 叠加ScaffoldinnerPadding 已经包含了系统栏 Insets。如果你在子组件中又手动添加 statusBarsPadding()navigationBarsPadding(),就会出现双重 padding,表现为顶部或底部出现多余的空白。

  2. 忽略导航栏对比度 :Edge-to-Edge 后,系统导航栏(三键/手势指示条)变成了透明的,如果你的底部内容是白色背景,白色手势指示条就"消失"了。需要设置 navigationBarContrastEnforced 或确保背景色与指示条有足够对比度。


四、实际应用

  • 在实际需求开发中,推荐按顺序一起联动使用
  • 假设你有一个 3 年历史的电商 App,需要全面现代化-重构。6 大 Skills 的推荐执行顺序:
步骤 Skill 理由
1️⃣ AGP 9 Upgrade 升级构建基础设施------若不升级,后续依赖都加不上
2️⃣ Migrate to Compose 迁移旧 XML 页面,为后续 Navigation 3 铺路
3️⃣ Navigation 3 在 Compose 基础上重建导航框架
4️⃣ Edge-to-Edge Compose 页面就绪后做全面屏适配
5️⃣ R8 Analyzer 优化 Release 包体积
6️⃣ Play Billing Upgrade 最后升级支付(风险最高,放到最后单独验证)

五、具体该如何使用?

这些 Skills 不需要手动阅读和执行。它们的设计目标是配合 AI 工具使用

工具 使用方式
Android Studio Gemini 将 Skill 放到项目的 .skills/ 目录,Agent Mode 自动加载
Android CLI android skills add --all 一键安装所有 Skill
Claude Code / Cursor 按各工具的 Skill 配置方式添加目录路径

也可以直接克隆仓库后手动放入项目:

bash 复制代码
git clone https://github.com/android/skills.git

六、不同阶段开发者的使用建议

🟢 初级开发者(0-2年)

  • 建议:优先关注 Edge-to-Edge、Migrate to Compose
  • 原因:初级开发者最常接到的任务就是"这个页面要改成 Compose"和"为什么我的页面在 Android 15 上显示不对"。先掌握这两个 Skill 的核心知识,能解决日常 80% 的 UI 问题。

🟡 中级开发者(2-5年)

  • 建议:优先关注 Navigation 3、AGP 9 Upgrade、R8 Analyzer
  • 原因:中级开发者开始参与架构决策和构建配置。Navigation 3 的状态驱动思想、AGP 9 的构建优化、R8 的 APK 瘦身------这些是晋升高级的必备知识。

🔴 高级开发者(5年+)

  • 建议:优先关注全面掌握 + 自定义 Skill
  • 原因:高级开发者不仅要掌握所有 6 个 Skill 的底层原理,更要学会创建团队级自定义 Skill,将项目的架构规范、迁移流程、最佳实践沉淀为可复用的 Skill 文件,赋能整个团队。

七、意义

android/skills 仓库标志着 Android 开发进入了一个新阶段:

从"人读文档写代码"到"AI 读指令改代码"。

Google 不再只是告诉你"怎么做"(文档),而是把"怎么做"直接交给 AI,让 AI 按照官方标准替你执行。开发者的角色从"手动操作者"转变为"意图表达者 + 质量审核者"。


八、 趋势展望

1. Skill 数量会快速增长

目前只有 6 个 Skill,但仓库结构已经为扩展做好了准备。可以预见,未来会有:

  • Kotlin Multiplatform 迁移 Skill
  • Compose Multiplatform 适配 Skill
  • Performance Baseline Profile 优化 Skill
  • Gradle Convention Plugin 创建 Skill
  • Android 16 新 API 适配 Skill

2. Agent Skills 将成为行业标准

android/skills 遵循 agentskills.io 开放标准,这意味着其他平台(iOS、Web、后端)也可以用同样的格式创建 Skill。未来我们可能会看到:

  • apple/skills(Swift/SwiftUI 迁移)
  • vercel/skills(Next.js 优化)
  • 各公司内部的 internal/skills

3. "不会用 AI 工具"将成为技术债

这套 Skill 体系的设计前提是开发者会使用 AI 编程工具。如果你还停留在"纯手写代码"阶段,你和懂得利用 AI Skill 的开发者之间的效率差距,会以指数级拉开。


最后的最后

📌 AI 不会取代 Android 开发者,但会使用 AI 的 Android 开发者,会取代不会使用的。 android/skills 就是 Google 给出的第一份官方答案。

💬 你最期待 Google 下一个 Skill 覆盖什么领域?欢迎评论区聊聊。

觉得有帮助?点个「在看」转发给你的 Android 同事 👆


📎 参考资源

资源 链接
android/skills GitHub 仓库 github.com/android/ski...
Android Skills 官方文档 developer.android.com/tools/agent...
Android CLI 文档 developer.android.com/tools/agent...
相关推荐
张风捷特烈2 小时前
状态管理大乱斗#06 | Riverpod 源码评析 (下) - 外功心法
android·前端·flutter
ZC跨境爬虫2 小时前
跟着 MDN 学 HTML day_16:(音频与视频处理——从画布滤镜到3D沉浸音频的进阶指南)
前端·javascript·ui·3d·html·音视频
魔术师Grace3 小时前
普通人学 AI,不要一上来就学提示词
前端·人工智能·程序员
m0_738120723 小时前
Webshell流量分析——常见扫描器AWVS,goby,xray流量特征分析
服务器·前端·安全·web安全·网络安全
三少爷的鞋3 小时前
Kotlin 协程 vs Java 虚拟线程:两种并发模型的对比
android
沐泽__3 小时前
多头注意力机制含义
ai编程
jimy13 小时前
记第一次运行codex
c语言·ai编程
神奇的程序员11 小时前
开发了一个管理本地开发环境的软件
前端·flutter
白云LDC12 小时前
Android Studio新建Vecter asset一直显示Loading icons(转圈圈)的解决办法
android·ide·android studio