1. Project Scenario Assessment
Before starting development, assess the current project state:
| Scenario | Characteristics | Approach |
|---|
| Empty Directory | No files present | Full initialization required, including Gradle Wrapper |
| Has Gradle Wrapper |
gradlew and
gradle/wrapper/ exist | Use
./gradlew directly for builds |
|
Android Studio Project | Complete project structure, may lack wrapper | Check wrapper, run
gradle wrapper if needed |
|
Incomplete Project | Partial files present | Check missing files, complete configuration |
Key Principles:
- - Before writing business logic, ensure
./gradlew assembleDebug succeeds - If
gradle.properties is missing, create it first and configure AndroidX
1.1 Required Files Checklist
CODEBLOCK0
2. Project Configuration
2.1 gradle.properties
CODEBLOCK1
Note: If you encounter OutOfMemoryError during build, increase -Xmx value. Large projects with many dependencies may require 8GB or more.
2.2 Dependency Declaration Standards
CODEBLOCK2
2.3 Build Variants & Product Flavors
Product Flavors allow you to create different versions of your app (e.g., free/paid, dev/staging/prod).
Configuration in app/build.gradle.kts:
CODEBLOCK3
Build Variant Naming: {flavor}{BuildType} → e.g., devDebug, INLINECODE10
Gradle Build Commands:
CODEBLOCK4
Access BuildConfig in Code:
Note: Starting from AGP 8.0, BuildConfig is no longer generated by default. You must explicitly enable it in your build.gradle.kts:
CODEBLOCK5
CODEBLOCK6
Flavor-Specific Source Sets:
CODEBLOCK7
Multiple Flavor Dimensions (e.g., environment + tier):
CODEBLOCK8
3. Kotlin Development Standards
3.1 Naming Conventions
| Type | Convention | Example |
|---|
| Class/Interface | PascalCase | INLINECODE13 , INLINECODE14 |
| Function/Variable |
camelCase |
getUserName(),
isLoading |
| Constant | SCREAMING_SNAKE |
MAX_RETRY_COUNT |
| Package | lowercase |
com.example.myapp |
| Composable | PascalCase |
@Composable fun UserCard() |
3.2 Code Standards (Important)
Null Safety:
CODEBLOCK9
Exception Handling:
CODEBLOCK10
3.3 Threading & Coroutines (Critical)
Thread Selection Principles:
| Operation Type | Thread | Description |
|---|
| UI Updates | INLINECODE20 | Update View, State, LiveData |
| Network Requests |
Dispatchers.IO | HTTP calls, API requests |
| File I/O |
Dispatchers.IO | Local storage, database operations |
| Compute Intensive |
Dispatchers.Default | JSON parsing, sorting, encryption |
Correct Usage:
CODEBLOCK11
Common Mistakes:
CODEBLOCK12
3.4 Visibility Rules
CODEBLOCK13
3.5 Common Syntax Pitfalls
CODEBLOCK14
3.6 Server Response Data Class Fields Must Be Nullable
CODEBLOCK15
3.7 Lifecycle Resource Management
CODEBLOCK16
3.8 Logging Level Usage
CODEBLOCK17
| Level | Use Case |
|---|
| INLINECODE24 (Info) | Normal flow, method entry, key parameters |
| INLINECODE25 (Warning) |
Recoverable exceptions, fallback handling, null returns |
|
e (Error) | Request failures, caught exceptions, unrecoverable errors |
4. Jetpack Compose Standards
4.1 @Composable Context Rules
CODEBLOCK18
4.2 State Management
CODEBLOCK19
4.3 Common Compose Mistakes
CODEBLOCK20
5. Resources & Icons
5.1 App Icon Requirements
Must provide multi-resolution icons:
| Directory | Size | Purpose |
|---|
| mipmap-mdpi | 48x48 | Baseline |
| mipmap-hdpi |
72x72 | 1.5x |
| mipmap-xhdpi | 96x96 | 2x |
| mipmap-xxhdpi | 144x144 | 3x |
| mipmap-xxxhdpi | 192x192 | 4x |
Recommended: Use Adaptive Icon (Android 8+):
CODEBLOCK21
5.2 Resource Naming Conventions
| Type | Prefix | Example |
|---|
| Layout | layout | INLINECODE27 |
| Image |
ic, img
, bg |
ic_user.png |
| Color | color_ |
color_primary |
| String | - |
app_name,
btn_submit |
5.3 Avoid Android Reserved Names (Important)
Variable names, resource IDs, colors, icons, and XML elements must not use Android reserved words or system resource names. Using reserved names causes build errors or resource conflicts.
Common Reserved Names to Avoid:
| Category | Reserved Names (Do NOT Use) |
|---|
| Colors | INLINECODE32 , foreground, transparent, white, INLINECODE36 |
| Icons/Drawables |
icon,
logo,
image,
drawable |
| Views |
view,
text,
button,
layout,
container |
| Attributes |
id,
name,
type,
style,
theme,
color |
| System |
app,
android,
content,
data,
action |
Examples:
CODEBLOCK22
CODEBLOCK23
CODEBLOCK24
6. Build Error Diagnosis & Fixes
6.1 Common Error Quick Reference
| Error Keyword | Cause | Fix |
|---|
| INLINECODE57 | Missing import or undefined | Check imports, verify dependencies |
| INLINECODE58 |
Type incompatibility | Check parameter types, add conversion |
|
Cannot access | Visibility issue | Check public/private/internal |
|
@Composable invocations | Composable context error | Ensure caller is also @Composable |
|
Duplicate class | Dependency conflict | Use
./gradlew dependencies to investigate |
|
AAPT: error | Resource file error | Check XML syntax and resource references |
6.2 Fix Best Practices
- 1. Read the complete error message first: Locate file and line number
- Check recent changes: Problems usually in latest modifications
- Clean Build: INLINECODE64
- Check dependency versions: Version conflicts are common causes
- Refresh dependencies if needed: Clear cache and rebuild
6.3 Debugging Commands
CODEBLOCK25
7. Material Design 3 Guidelines
Review Android UI files for compliance with Material Design 3 Guidelines and Android best practices.
Design Philosophy
M3 Core Principles
| Principle | Description |
|---|
| Personal | Dynamic color based on user preferences and wallpaper |
| Adaptive |
Responsive across all screen sizes and form factors |
|
Expressive | Bold colors and typography with personality |
|
Accessible | Inclusive design for all users |
M3 Expressive (Latest)
The latest evolution adds emotion-driven UX through:
- - Vibrant, dynamic colors
- Intuitive motion physics
- Adaptive components
- Flexible typography
- Contrasting shapes (35 new shape options)
App Style Selection
Critical Decision: Match visual style to app category and target audience.
| App Category | Visual Style | Key Characteristics |
|---|
| Utility/Tool | Minimalist | Clean, efficient, neutral colors |
| Finance/Banking |
Professional Trust | Conservative colors, security-focused |
| Health/Wellness | Calm & Natural | Soft colors, organic shapes |
| Kids (3-5) | Playful Simple | Bright colors, large targets (56dp+) |
| Kids (6-12) | Fun & Engaging | Vibrant, gamified feedback |
| Social/Entertainment | Expressive | Brand-driven, gesture-rich |
| Productivity | Clean & Focused | Minimal, high contrast |
| E-commerce | Conversion-focused | Clear CTAs, scannable |
See Design Style Guide for detailed style profiles.
Quick Reference: Key Specifications
Color Contrast Requirements
| Element | Minimum Ratio |
|---|
| Body text | 4.5:1 |
| Large text (18sp+) |
3:1 |
| UI components |
3:1 |
Touch Targets
| Type | Size |
|---|
| Minimum | 48 × 48dp |
| Recommended (primary actions) |
56 × 56dp |
| Kids apps | 56dp+ |
| Spacing between targets | 8dp minimum |
8dp Grid System
| Token | Value | Usage |
|---|
| xs | 4dp | Icon padding |
| sm |
8dp | Tight spacing |
| md | 16dp | Default padding |
| lg | 24dp | Section spacing |
| xl | 32dp | Large gaps |
| xxl | 48dp | Screen margins |
Typography Scale (Summary)
| Category | Sizes |
|---|
| Display | 57sp, 45sp, 36sp |
| Headline |
32sp, 28sp, 24sp |
| Title | 22sp, 16sp, 14sp |
| Body | 16sp, 14sp, 12sp |
| Label | 14sp, 12sp, 11sp |
Animation Duration
| Type | Duration |
|---|
| Micro (ripples) | 50-100ms |
| Short (simple) |
100-200ms |
| Medium (expand/collapse) | 200-300ms |
| Long (complex) | 300-500ms |
Component Dimensions
| Component | Height | Min Width |
|---|
| Button | 40dp | 64dp |
| FAB |
56dp | 56dp |
| Text Field | 56dp | 280dp |
| App Bar | 64dp | - |
| Bottom Nav | 80dp | - |
Anti-Patterns (Must Avoid)
UI Anti-Patterns
- - More than 5 bottom navigation items
- Multiple FABs on same screen
- Touch targets smaller than 48dp
- Inconsistent spacing (non-8dp multiples)
- Missing dark theme support
- Text on colored backgrounds without contrast check
Performance Anti-Patterns
- - Startup time > 2 seconds without progress indicator
- Frame rate < 60 FPS (> 16ms per frame)
- Crash rate > 1.09% (Google Play threshold)
- ANR rate > 0.47% (Google Play threshold)
Accessibility Anti-Patterns
- - Missing contentDescription on interactive elements
- Element type in labels (e.g., "Save button" instead of "Save")
- Complex gestures in kids apps
- Text-only buttons for non-readers
Review Checklist
- - [ ] 8dp spacing grid compliance
- [ ] 48dp minimum touch targets
- [ ] Proper typography scale usage
- [ ] Color contrast compliance (4.5:1+ for text)
- [ ] Dark theme support
- [ ] contentDescription on all interactive elements
- [ ] Startup < 2 seconds or shows progress
- [ ] Visual style matches app category
Design References
| Topic | Reference |
|---|
| Colors, Typography, Spacing, Shapes | Visual Design |
| Animation & Transitions |
Motion System |
| Accessibility Guidelines |
Accessibility |
| Large Screens & Foldables |
Adaptive Screens |
| Android Vitals & Performance |
Performance & Stability |
| Privacy & Security |
Privacy & Security |
| Audio, Video, Notifications |
Functional Requirements |
| App Style by Category |
Design Style Guide |
8. Testing
Note: Only add test dependencies when the user explicitly asks for testing.
A well-tested Android app uses layered testing: fast local unit tests for logic, instrumentation tests for UI and integration, and Gradle Managed Devices to run emulators reproducibly on any machine — including CI.
8.1 Test Dependencies
Before adding test dependencies, inspect the project's existing versions to avoid conflicts:
- 1. Check
gradle/libs.versions.toml — if present, add test deps using the project's version catalog style - Check existing
build.gradle.kts for already-pinned dependency versions - Match version families using the table below
Version Alignment Rules:
| Test Dependency | Must Align With | How to Check |
|---|
| INLINECODE67 | Project's kotlinx-coroutines-core version | Search for kotlinx-coroutines in build files or version catalog |
| INLINECODE70 |
Project's Compose BOM or
compose-compiler | Search for
compose-bom or
compose.compiler in build files |
|
espresso-* | All Espresso artifacts must use the same version | Search for
espresso in build files |
|
androidx.test:runner,
rules,
ext:junit | Should use compatible AndroidX Test versions | Search for
androidx.test in build files |
|
mockk | Must support the project's Kotlin version | Check
kotlin version in root
build.gradle.kts or version catalog |
Dependencies Reference — add only the groups you need:
CODEBLOCK26
Note: If the project uses a Compose BOM, ui-test-junit4 and ui-test-manifest don't need explicit versions — the BOM manages them.
Enable Robolectric resource support in the android block:
CODEBLOCK27
8.2 Testing by Layer
| Layer | Location | Runs On | Speed | Use For |
|---|
| Unit (JUnit) | INLINECODE86 | JVM | ~ms | ViewModels, repos, mappers, validators |
| Unit + Robolectric |
src/test/ | JVM + simulated Android | ~100ms | Code needing Context, resources, SharedPrefs |
| Compose UI (local) |
src/test/ | JVM + Robolectric | ~100ms | Composable rendering & interaction |
| Espresso |
src/androidTest/ | Device/Emulator | ~seconds | View-based UI flows, Intents, DB integration |
| Compose UI (device)|
src/androidTest/ | Device/Emulator | ~seconds | Full Compose UI flows with real rendering |
| UI Automator |
src/androidTest/ | Device/Emulator | ~seconds | System dialogs, notifications, multi-app |
| Managed Device |
src/androidTest/ | Gradle-managed AVD | ~minutes (first run) | CI, matrix testing across API levels |
See Testing for detailed examples, code patterns, and Gradle Managed Device configuration.
8.3 Testing Commands
CODEBLOCK28
1. 项目场景评估
在开始开发之前,评估当前项目状态:
| 场景 | 特征 | 方法 |
|---|
| 空目录 | 无文件存在 | 需要完整初始化,包括 Gradle Wrapper |
| 已有 Gradle Wrapper |
存在 gradlew 和 gradle/wrapper/ 目录 | 直接使用 ./gradlew 进行构建 |
|
Android Studio 项目 | 完整的项目结构,可能缺少 Wrapper | 检查 Wrapper,如有需要运行 gradle wrapper |
|
不完整的项目 | 存在部分文件 | 检查缺失文件,完成配置 |
关键原则:
- - 在编写业务逻辑之前,确保 ./gradlew assembleDebug 能够成功执行
- 如果缺少 gradle.properties,请先创建它并配置 AndroidX
1.1 必需文件清单
MyApp/
├── gradle.properties # 配置 AndroidX 和其他设置
├── settings.gradle.kts
├── build.gradle.kts # 根级别
├── gradle/wrapper/
│ └── gradle-wrapper.properties
├── app/
│ ├── build.gradle.kts # 模块级别
│ └── src/main/
│ ├── AndroidManifest.xml
│ ├── java/com/example/myapp/
│ │ └── MainActivity.kt
│ └── res/
│ ├── values/
│ │ ├── strings.xml
│ │ ├── colors.xml
│ │ └── themes.xml
│ └── mipmap-*/ # 应用图标
2. 项目配置
2.1 gradle.properties
properties
必需配置
android.useAndroidX=true
android.enableJetifier=true
构建优化
org.gradle.parallel=true
kotlin.code.style=official
JVM 内存设置(根据项目大小调整)
小型项目:2048m,中型:4096m,大型:8192m+
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
注意:如果在构建过程中遇到 OutOfMemoryError,请增加 -Xmx 的值。依赖较多的大型项目可能需要 8GB 或更多内存。
2.2 依赖声明标准
kotlin
dependencies {
// 使用 BOM 管理 Compose 版本
implementation(platform(androidx.compose:compose-bom:2024.02.00))
implementation(androidx.compose.ui:ui)
implementation(androidx.compose.material3:material3)
// Activity & ViewModel
implementation(androidx.activity:activity-compose:1.8.2)
implementation(androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0)
}
2.3 构建变体与产品风味
产品风味允许您创建应用的不同版本(例如,免费/付费,开发/预发布/生产)。
在 app/build.gradle.kts 中的配置:
kotlin
android {
// 定义风味维度
flavorDimensions += environment
productFlavors {
create(dev) {
dimension = environment
applicationIdSuffix = .dev
versionNameSuffix = -dev
// 每个风味的不同配置值
buildConfigField(String, APIBASEURL, \https://dev-api.example.com\)
buildConfigField(Boolean, ENABLE_LOGGING, true)
// 不同的资源
resValue(string, app_name, MyApp Dev)
}
create(staging) {
dimension = environment
applicationIdSuffix = .staging
versionNameSuffix = -staging
buildConfigField(String, APIBASEURL, \https://staging-api.example.com\)
buildConfigField(Boolean, ENABLE_LOGGING, true)
resValue(string, app_name, MyApp Staging)
}
create(prod) {
dimension = environment
// 生产版本无后缀
buildConfigField(String, APIBASEURL, \https://api.example.com\)
buildConfigField(Boolean, ENABLE_LOGGING, false)
resValue(string, app_name, MyApp)
}
}
buildTypes {
debug {
isDebuggable = true
isMinifyEnabled = false
}
release {
isDebuggable = false
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro)
}
}
}
构建变体命名:{flavor}{BuildType} → 例如,devDebug,prodRelease
Gradle 构建命令:
bash
列出所有可用的构建变体
./gradlew tasks --group=build
构建特定变体(风味 + 构建类型)
./gradlew assembleDevDebug # Dev 风味,Debug 构建
./gradlew assembleStagingDebug # Staging 风味,Debug 构建
./gradlew assembleProdRelease # Prod 风味,Release 构建
构建特定风味的所有变体
./gradlew assembleDev # 所有 Dev 变体(debug + release)
./gradlew assembleProd # 所有 Prod 变体
构建特定构建类型的所有变体
./gradlew assembleDebug # 所有风味,Debug 构建
./gradlew assembleRelease # 所有风味,Release 构建
将特定变体安装到设备
./gradlew installDevDebug
./gradlew installProdRelease
在一个命令中构建并安装
./gradlew installDevDebug && adb shell am start -n com.example.myapp.dev/.MainActivity
在代码中访问 BuildConfig:
注意:从 AGP 8.0 开始,默认不再生成 BuildConfig。您必须在 build.gradle.kts 中显式启用它:
kotlin
android {
buildFeatures {
buildConfig = true
}
}
kotlin
// 在代码中使用构建配置值
val apiUrl = BuildConfig.API
BASEURL
val isLoggingEnabled = BuildConfig.ENABLE_LOGGING
if (BuildConfig.DEBUG) {
// 仅调试代码
}
风味特定的源集:
app/src/
├── main/ # 所有风味共享的代码
├── dev/ # 仅 Dev 的代码和资源
│ ├── java/
│ └── res/
├── staging/ # 仅 Staging 的代码和资源
├── prod/ # 仅 Prod 的代码和资源
├── debug/ # Debug 构建类型代码
└── release/ # Release 构建类型代码
多个风味维度(例如,environment + tier):
kotlin
android {
flavorDimensions += listOf(environment, tier)
productFlavors {
create(dev) { dimension = environment }
create(prod) { dimension = environment }
create(free) { dimension = tier }
create(paid) { dimension = tier }
}
}
// 结果:devFreeDebug, devPaidDebug, prodFreeRelease 等
3. Kotlin 开发标准
3.1 命名约定
| 类型 | 约定 | 示例 |
|---|
| 类/接口 | PascalCase | UserRepository,MainActivity |
| 函数/变量 |
camelCase | getUserName(),isLoading |
| 常量 | SCREAMING
SNAKE | MAXRETRY_COUNT |
| 包 | 小写 | com.example.myapp |
| Composable | PascalCase | @Composable fun UserCard() |
3.2 代码标准(重要)
空安全:
kotlin
// ❌ 避免:非空断言 !!(可能崩溃)
val name = user!!.name
// ✅ 推荐:安全调用 + 默认值
val name = user?.name ?: Unknown
// ✅ 推荐:let 处理
user?.let { processUser(it) }
异常处理:
kotlin
// ❌ 避免:在业务层随意使用 try-catch 吞掉异常
fun loadData() {
try {
val data = api.fetch()
} catch (e: Exception) {
// 吞掉异常,难以调试
}
}
// ✅ 推荐:让异常传播,在适当的层处理
suspend fun loadData(): Result<