Token导航 LogoToken导航

Agent Skill · 效率

android-native-dev-bak(Android 原生开发包)

android-native-dev-bak 用于辅助前端页面、组件、样式和交互逻辑开发,适合在 OpenClaw 中需要维护前端项目、生成组件或检查界面实现时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

android-native-dev-bak 是效率类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为执行命令;许可证为 MIT-0,第三方扫描已通过,按安装量在效率类的 21,003 个 Skill 里排第 15,281。

总安装 3,158周安装 129GitHub Stars 公开资料未说明下载 1,011核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:android-native-dev-bak(Android 原生开发包)
来源仓库:https://github.com/roger0808/android-native-dev-bak
安装命令:
openclaw skills install android-native-dev-bak
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install android-native-dev-bak

这个 Skill 是做什么的

效率类 Skill 把重复的整理、汇总、转换工作交给助手完成,减少手工复制粘贴。

用于辅助前端页面、组件、样式和交互逻辑开发。适合在 OpenClaw 中维护前端项目、生成组件或检查界面实现。安装命令:openclaw skills install android-native-dev-bak,适用于 OpenClaw 宿主。建议结合来源仓库和原始 README 继续核验具体用法。

安装前应确认权限范围和维护状态,避免触发不必要的联网或文件操作。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install android-native-dev-bak;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要执行命令,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

android-native-dev-bak 怎么安装?

在终端执行 openclaw skills install android-native-dev-bak。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

android-native-dev-bak 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

android-native-dev-bak 需要什么权限?

权限级别是执行命令。安装流程涉及命令执行,可能通过 openclaw skills install android-native-dev-bak 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

android-native-dev-bak 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

android-native-dev-bak 用的人多吗?

公开数据是累计安装 3,158 次,近一周安装 129 次,下载 1,011 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

android-native-dev-bak 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要执行命令,装到常用环境前要先评估影响面。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理效率类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 不能接受 Skill 在你机器上执行命令的人。
  • 需要厂商级技术支持和 SLA 的生产系统。

效率类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
github

GitHub 代码协作 · OpenClaw

7,632,918545需要联网MIT-0通过
nano-pdf

Nano PDF 文档 · OpenClaw

4,249,476231需要联网MIT-0通过
auto-updater

自动更新程序 · OpenClaw

2,964,063386操作浏览器MIT-0通过
video-frames

视频帧 · OpenClaw

2,621,304112需要联网MIT-0通过
gemini

Gemini 助手 · OpenClaw

2,547,39648需要联网MIT-0有提醒
android-native-dev-bak

Android 原生开发包 · 本页

3,158—执行命令MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
android-native-dev
description
Android native application development and UI design guide. Covers Material Design 3, Kotlin/Compose development, project configuration, accessibility, and build troubleshooting. Read this before Android native application development.
license
MIT
metadata
version
1.0.0
category
mobile
sources

1. Project Scenario Assessment

Before starting development, assess the current project state:

ScenarioCharacteristicsApproach
Empty DirectoryNo files presentFull initialization required, including Gradle Wrapper
Has Gradle Wrappergradlew and gradle/wrapper/ existUse ./gradlew directly for builds
Android Studio ProjectComplete project structure, may lack wrapperCheck wrapper, run gradle wrapper if needed
Incomplete ProjectPartial files presentCheck 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

MyApp/
├── gradle.properties          # Configure AndroidX and other settings
├── settings.gradle.kts
├── build.gradle.kts           # Root level
├── gradle/wrapper/
│   └── gradle-wrapper.properties
├── app/
│   ├── build.gradle.kts       # Module level
│   └── src/main/
│       ├── AndroidManifest.xml
│       ├── java/com/example/myapp/
│       │   └── MainActivity.kt
│       └── res/
│           ├── values/
│           │   ├── strings.xml
│           │   ├── colors.xml
│           │   └── themes.xml
│           └── mipmap-*/       # App icons

2. Project Configuration

2.1 gradle.properties

# Required configuration
android.useAndroidX=true
android.enableJetifier=true

# Build optimization
org.gradle.parallel=true
kotlin.code.style=official

# JVM memory settings (adjust based on project size)
# Small projects: 2048m, Medium: 4096m, Large: 8192m+
# org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
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

dependencies {
    // Use BOM to manage Compose versions
    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 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:

android {
    // Define flavor dimensions
    flavorDimensions += "environment"
    
    productFlavors {
        create("dev") {
            dimension = "environment"
            applicationIdSuffix = ".dev"
            versionNameSuffix = "-dev"
            
            // Different config values per flavor
            buildConfigField("String", "API_BASE_URL", "\"https://dev-api.example.com\"")
            buildConfigField("Boolean", "ENABLE_LOGGING", "true")
            
            // Different resources
            resValue("string", "app_name", "MyApp Dev")
        }
        
        create("staging") {
            dimension = "environment"
            applicationIdSuffix = ".staging"
            versionNameSuffix = "-staging"
            
            buildConfigField("String", "API_BASE_URL", "\"https://staging-api.example.com\"")
            buildConfigField("Boolean", "ENABLE_LOGGING", "true")
            resValue("string", "app_name", "MyApp Staging")
        }
        
        create("prod") {
            dimension = "environment"
            // No suffix for production
            
            buildConfigField("String", "API_BASE_URL", "\"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")
        }
    }
}

Build Variant Naming: {flavor}{BuildType} → e.g., devDebug, prodRelease

Gradle Build Commands:

# List all available build variants
./gradlew tasks --group="build"

# Build specific variant (flavor + buildType)
./gradlew assembleDevDebug        # Dev flavor, Debug build
./gradlew assembleStagingDebug    # Staging flavor, Debug build
./gradlew assembleProdRelease     # Prod flavor, Release build

# Build all variants of a specific flavor
./gradlew assembleDev             # All Dev variants (debug + release)
./gradlew assembleProd            # All Prod variants

# Build all variants of a specific build type
./gradlew assembleDebug           # All flavors, Debug build
./gradlew assembleRelease         # All flavors, Release build

# Install specific variant to device
./gradlew installDevDebug
./gradlew installProdRelease

# Build and install in one command
./gradlew installDevDebug && adb shell am start -n com.example.myapp.dev/.MainActivity

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: ``kotlin android { buildFeatures { buildConfig = true } } ``
// Use build config values in your code
val apiUrl = BuildConfig.API_BASE_URL
val isLoggingEnabled = BuildConfig.ENABLE_LOGGING

if (BuildConfig.DEBUG) {
    // Debug-only code
}

Flavor-Specific Source Sets:

app/src/
├── main/           # Shared code for all flavors
├── dev/            # Dev-only code and resources
│   ├── java/
│   └── res/
├── staging/        # Staging-only code and resources
├── prod/           # Prod-only code and resources
├── debug/          # Debug build type code
└── release/        # Release build type code

Multiple Flavor Dimensions (e.g., environment + tier):

android {
    flavorDimensions += listOf("environment", "tier")
    
    productFlavors {
        create("dev") { dimension = "environment" }
        create("prod") { dimension = "environment" }
        
        create("free") { dimension = "tier" }
        create("paid") { dimension = "tier" }
    }
}
// Results in: devFreeDebug, devPaidDebug, prodFreeRelease, etc.

3. Kotlin Development Standards

3.1 Naming Conventions

TypeConventionExample
Class/InterfacePascalCaseUserRepository, MainActivity
Function/VariablecamelCasegetUserName(), isLoading
ConstantSCREAMING_SNAKEMAX_RETRY_COUNT
Packagelowercasecom.example.myapp
ComposablePascalCase@Composable fun UserCard()

3.2 Code Standards (Important)

Null Safety:

// ❌ Avoid: Non-null assertion !! (may crash)
val name = user!!.name

// ✅ Recommended: Safe call + default value
val name = user?.name ?: "Unknown"

// ✅ Recommended: let handling
user?.let { processUser(it) }

Exception Handling:

// ❌ Avoid: Random try-catch in business layer swallowing exceptions
fun loadData() {
    try {
        val data = api.fetch()
    } catch (e: Exception) {
        // Swallowing exception, hard to debug
    }
}

// ✅ Recommended: Let exceptions propagate, handle at appropriate layer
suspend fun loadData(): Result<Data> {
    return try {
        Result.success(api.fetch())
    } catch (e: Exception) {
        Result.failure(e)  // Wrap and return, let caller decide handling
    }
}

// ✅ Recommended: Unified handling in ViewModel
viewModelScope.launch {
    runCatching { repository.loadData() }
        .onSuccess { _uiState.value = UiState.Success(it) }
        .onFailure { _uiState.value = UiState.Error(it.message) }
}

3.3 Threading & Coroutines (Critical)

Thread Selection Principles:

Operation TypeThreadDescription
UI UpdatesDispatchers.MainUpdate View, State, LiveData
Network RequestsDispatchers.IOHTTP calls, API requests
File I/ODispatchers.IOLocal storage, database operations
Compute IntensiveDispatchers.DefaultJSON parsing, sorting, encryption

Correct Usage:

// In ViewModel
viewModelScope.launch {
    // Default Main thread, can update UI State
    _uiState.value = UiState.Loading
    
    // Switch to IO thread for network request
    val result = withContext(Dispatchers.IO) {
        repository.fetchData()
    }
    
    // Automatically returns to Main thread, update UI
    _uiState.value = UiState.Success(result)
}

// In Repository (suspend functions should be main-safe)
suspend fun fetchData(): Data = withContext(Dispatchers.IO) {
    api.getData()
}

Common Mistakes:

// ❌ Wrong: Updating UI on IO thread
viewModelScope.launch(Dispatchers.IO) {
    val data = api.fetch()
    _uiState.value = data  // Crash or warning!
}

// ❌ Wrong: Executing time-consuming operation on Main thread
viewModelScope.launch {
    val data = api.fetch()  // Blocking main thread! ANR
}

// ✅ Correct: Fetch on IO, update on Main
viewModelScope.launch {
    val data = withContext(Dispatchers.IO) { api.fetch() }
    _uiState.value = data
}

3.4 Visibility Rules

// Default is public, declare explicitly when needed
class UserRepository {           // public
    private val cache = mutableMapOf<String, User>()  // Visible only within class
    internal fun clearCache() {} // Visible only within module
}

// data class properties are public by default, be careful when used across modules
data class User(
    val id: String,       // public
    val name: String
)

3.5 Common Syntax Pitfalls

// ❌ Wrong: Accessing uninitialized lateinit
class MyViewModel : ViewModel() {
    lateinit var data: String
    fun process() = data.length  // May crash
}

// ✅ Correct: Use nullable or default value
class MyViewModel : ViewModel() {
    var data: String? = null
    fun process() = data?.length ?: 0
}

// ❌ Wrong: Using return in lambda
list.forEach { item ->
    if (item.isEmpty()) return  // Returns from outer function!
}

// ✅ Correct: Use return@forEach
list.forEach { item ->
    if (item.isEmpty()) return@forEach
}

3.6 Server Response Data Class Fields Must Be Nullable

// ❌ Wrong: Fields declared as non-null (server may not return them)
data class UserResponse(
    val id: String = "",
    val name: String = "",
    val avatar: String = ""
)

// ✅ Correct: All fields declared as nullable
data class UserResponse(
    @SerializedName("id")
    val id: String? = null,
    @SerializedName("name")
    val name: String? = null,
    @SerializedName("avatar")
    val avatar: String? = null
)

3.7 Lifecycle Resource Management

// ❌ Wrong: Only adding Observer, not removing
class MyView : View {
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        activity?.lifecycle?.addObserver(this)
    }
    // Memory leak!
}

// ✅ Correct: Paired add and remove
class MyView : View {
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        activity?.lifecycle?.addObserver(this)
    }

    override fun onDetachedFromWindow() {
        activity?.lifecycle?.removeObserver(this)
        super.onDetachedFromWindow()
    }
}

3.8 Logging Level Usage

import android.util.Log

// Info: Key checkpoints in normal flow
Log.i(TAG, "loadData: started, userId = $userId")

// Warning: Abnormal but recoverable situations
Log.w(TAG, "loadData: cache miss, fallback to network")

// Error: Failure/error situations
Log.e(TAG, "loadData failed: ${error.message}")
LevelUse Case
i (Info)Normal flow, method entry, key parameters
w (Warning)Recoverable exceptions, fallback handling, null returns
e (Error)Request failures, caught exceptions, unrecoverable errors

4. Jetpack Compose Standards

4.1 @Composable Context Rules

// ❌ Wrong: Calling Composable from non-Composable function
fun showError(message: String) {
    Text(message)  // Compile error!
}

// ✅ Correct: Mark as @Composable
@Composable
fun ErrorMessage(message: String) {
    Text(message)
}

// ❌ Wrong: Using suspend outside LaunchedEffect
@Composable
fun MyScreen() {
    val data = fetchData()  // Error!
}

// ✅ Correct: Use LaunchedEffect
@Composable
fun MyScreen() {
    var data by remember { mutableStateOf<Data?>(null) }
    LaunchedEffect(Unit) {
        data = fetchData()
    }
}

4.2 State Management

// Basic State
var count by remember { mutableStateOf(0) }

// Derived State (avoid redundant computation)
val isEven by remember { derivedStateOf { count % 2 == 0 } }

// Persist across recomposition (e.g., scroll position)
val scrollState = rememberScrollState()

// State in ViewModel
class MyViewModel : ViewModel() {
    private val _uiState = MutableStateFlow(UiState())
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()
}

4.3 Common Compose Mistakes

// ❌ Wrong: Creating objects in Composable (created on every recomposition)
@Composable
fun MyScreen() {
    val viewModel = MyViewModel()  // Wrong!
}

// ✅ Correct: Use viewModel() or remember
@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {
    // ...
}

5. Resources & Icons

5.1 App Icon Requirements

Must provide multi-resolution icons:

DirectorySizePurpose
mipmap-mdpi48x48Baseline
mipmap-hdpi72x721.5x
mipmap-xhdpi96x962x
mipmap-xxhdpi144x1443x
mipmap-xxxhdpi192x1924x

Recommended: Use Adaptive Icon (Android 8+):

<!-- res/mipmap-anydpi-v26/ic_launcher.xml -->
<adaptive-icon>
    <background android:drawable="@color/ic_launcher_background"/>
    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

5.2 Resource Naming Conventions

TypePrefixExample
Layoutlayout_layout_main.xml
Imageic_, img_, bg_ic_user.png
Colorcolor_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:

CategoryReserved Names (Do NOT Use)
Colorsbackground, foreground, transparent, white, black
Icons/Drawablesicon, logo, image, drawable
Viewsview, text, button, layout, container
Attributesid, name, type, style, theme, color
Systemapp, android, content, data, action

Examples:

<!-- ❌ Wrong: Using reserved names -->
<color name="background">#FFFFFF</color>
<color name="icon">#000000</color>

<!-- ✅ Correct: Add prefix or specific naming -->
<color name="app_background">#FFFFFF</color>
<color name="icon_primary">#000000</color>
// ❌ Wrong: Variable names conflict with system
val icon = R.drawable.my_icon
val background = Color.White

// ✅ Correct: Use descriptive names
val appIcon = R.drawable.my_icon
val screenBackground = Color.White
<!-- ❌ Wrong: Drawable name conflicts -->
<ImageView android:src="@drawable/icon" />

<!-- ✅ Correct: Add prefix -->
<ImageView android:src="@drawable/ic_home" />

6. Build Error Diagnosis & Fixes

6.1 Common Error Quick Reference

Error KeywordCauseFix
Unresolved referenceMissing import or undefinedCheck imports, verify dependencies
Type mismatchType incompatibilityCheck parameter types, add conversion
Cannot accessVisibility issueCheck public/private/internal
@Composable invocationsComposable context errorEnsure caller is also @Composable
Duplicate classDependency conflictUse ./gradlew dependencies to investigate
AAPT: errorResource file errorCheck XML syntax and resource references

6.2 Fix Best Practices

  1. Read the complete error message first: Locate file and line number
  2. Check recent changes: Problems usually in latest modifications
  3. Clean Build: ./gradlew clean assembleDebug
  4. Check dependency versions: Version conflicts are common causes
  5. Refresh dependencies if needed: Clear cache and rebuild

6.3 Debugging Commands

# Clean and build
./gradlew clean assembleDebug

# View dependency tree (investigate conflicts)
./gradlew :app:dependencies

# View detailed errors
./gradlew assembleDebug --stacktrace

# Refresh dependencies
./gradlew --refresh-dependencies

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
PrincipleDescription
PersonalDynamic color based on user preferences and wallpaper
AdaptiveResponsive across all screen sizes and form factors
ExpressiveBold colors and typography with personality
AccessibleInclusive 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 CategoryVisual StyleKey Characteristics
Utility/ToolMinimalistClean, efficient, neutral colors
Finance/BankingProfessional TrustConservative colors, security-focused
Health/WellnessCalm & NaturalSoft colors, organic shapes
Kids (3-5)Playful SimpleBright colors, large targets (56dp+)
Kids (6-12)Fun & EngagingVibrant, gamified feedback
Social/EntertainmentExpressiveBrand-driven, gesture-rich
ProductivityClean & FocusedMinimal, high contrast
E-commerceConversion-focusedClear CTAs, scannable

See Design Style Guide for detailed style profiles.

Quick Reference: Key Specifications

Color Contrast Requirements
ElementMinimum Ratio
Body text4.5:1
Large text (18sp+)3:1
UI components3:1
Touch Targets
TypeSize
Minimum48 × 48dp
Recommended (primary actions)56 × 56dp
Kids apps56dp+
Spacing between targets8dp minimum
8dp Grid System
TokenValueUsage
xs4dpIcon padding
sm8dpTight spacing
md16dpDefault padding
lg24dpSection spacing
xl32dpLarge gaps
xxl48dpScreen margins
Typography Scale (Summary)
CategorySizes
Display57sp, 45sp, 36sp
Headline32sp, 28sp, 24sp
Title22sp, 16sp, 14sp
Body16sp, 14sp, 12sp
Label14sp, 12sp, 11sp
Animation Duration
TypeDuration
Micro (ripples)50-100ms
Short (simple)100-200ms
Medium (expand/collapse)200-300ms
Long (complex)300-500ms
Component Dimensions
ComponentHeightMin Width
Button40dp64dp
FAB56dp56dp
Text Field56dp280dp
App Bar64dp-
Bottom Nav80dp-

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

TopicReference
Colors, Typography, Spacing, ShapesVisual Design
Animation & TransitionsMotion System
Accessibility GuidelinesAccessibility
Large Screens & FoldablesAdaptive Screens
Android Vitals & PerformancePerformance & Stability
Privacy & SecurityPrivacy & Security
Audio, Video, NotificationsFunctional Requirements
App Style by CategoryDesign 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
  2. Check existing build.gradle.kts for already-pinned dependency versions
  3. Match version families using the table below

Version Alignment Rules:

Test DependencyMust Align WithHow to Check
kotlinx-coroutines-testProject's kotlinx-coroutines-core versionSearch for kotlinx-coroutines in build files or version catalog
compose-ui-test-junit4Project's Compose BOM or compose-compilerSearch for compose-bom or compose.compiler in build files
espresso-*All Espresso artifacts must use the same versionSearch for espresso in build files
androidx.test:runner, rules, ext:junitShould use compatible AndroidX Test versionsSearch for androidx.test in build files
mockkMust support the project's Kotlin versionCheck kotlin version in root build.gradle.kts or version catalog

Dependencies Reference — add only the groups you need:

dependencies {
    // --- Local unit tests (src/test/) ---
    testImplementation("junit:junit:<version>")                          // 4.13.2+
    testImplementation("org.robolectric:robolectric:<version>")          // 4.16.1+
    testImplementation("io.mockk:mockk:<version>")                      // match Kotlin version
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:<version>")  // match coroutines-core
    testImplementation("androidx.arch.core:core-testing:<version>")      // InstantTaskExecutorRule for LiveData
    testImplementation("app.cash.turbine:turbine:<version>")             // Flow/StateFlow testing

    // --- Instrumentation tests (src/androidTest/) ---
    androidTestImplementation("androidx.test.ext:junit:<version>")
    androidTestImplementation("androidx.test:runner:<version>")
    androidTestImplementation("androidx.test:rules:<version>")
    androidTestImplementation("androidx.test.espresso:espresso-core:<version>")
    androidTestImplementation("androidx.test.espresso:espresso-contrib:<version>")   // RecyclerView, Drawer
    androidTestImplementation("androidx.test.espresso:espresso-intents:<version>")   // Intent verification
    androidTestImplementation("androidx.test.espresso:espresso-idling-resource:<version>")
    androidTestImplementation("androidx.test.uiautomator:uiautomator:<version>")

    // --- Compose UI tests (only if project uses Compose) ---
    androidTestImplementation("androidx.compose.ui:ui-test-junit4")      // version from Compose BOM
    debugImplementation("androidx.compose.ui:ui-test-manifest")          // required for createComposeRule
}
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:

android {
    testOptions {
        unitTests.isIncludeAndroidResources = true  // required for Robolectric
    }
}

8.2 Testing by Layer

LayerLocationRuns OnSpeedUse For
Unit (JUnit)src/test/JVM~msViewModels, repos, mappers, validators
Unit + Robolectricsrc/test/JVM + simulated Android~100msCode needing Context, resources, SharedPrefs
Compose UI (local)src/test/JVM + Robolectric~100msComposable rendering & interaction
Espressosrc/androidTest/Device/Emulator~secondsView-based UI flows, Intents, DB integration
Compose UI (device)src/androidTest/Device/Emulator~secondsFull Compose UI flows with real rendering
UI Automatorsrc/androidTest/Device/Emulator~secondsSystem dialogs, notifications, multi-app
Managed Devicesrc/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

# Local unit tests (fast, no emulator)
./gradlew test                          # all modules
./gradlew :app:testDebugUnitTest        # app module, debug variant

# Single test class
./gradlew :app:testDebugUnitTest --tests "com.example.myapp.CounterViewModelTest"

# Instrumentation tests (requires device or managed device)
./gradlew connectedDebugAndroidTest     # on connected device
./gradlew pixel6Api34DebugAndroidTest   # on managed device

# Both together
./gradlew test connectedDebugAndroidTest

# Test with coverage report (JaCoCo)
./gradlew testDebugUnitTest jacocoTestReport

平台分布

OpenClaw

83.52%
按下载量换算844

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

执行命令

安装流程涉及命令执行,可能通过 openclaw skills install android-native-dev-bak 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills