| name | Android |
| description | Android app development with gomobile, Gradle, and modern tooling. USE WHEN building Android apps, working with gomobile bindings, managing Android SDK/NDK, running emulators, debugging with adb, or publishing to Play Store. |
Android Development
Expert guidance on Android application development with first-class support for Go integration via gomobile, modern Gradle build system, SDK/NDK management, and deployment workflows.
Purpose
Guide Android development following official best practices, with specialized support for:
- Gomobile integration: Building Go libraries (AAR) and apps for Android
- Modern Gradle: Kotlin DSL, version catalogs, and build optimization
- SDK management: Android SDK, NDK, and command-line tools
- Development workflows: Build, debug, test, and deploy Android apps
- Nix integration: Using Android tools in NixOS environments
Context Detection
This skill activates when:
- Current directory contains
build.gradle,build.gradle.kts, orAndroidManifest.xml - Git repository has Android project structure (
app/,gradle/) - User mentions gomobile, Android SDK, adb, or Android development
- Working with
.aar,.apk, or.aabfiles - Commands like
gradle,adb,gomobile, orsdkmanagerare mentioned
Workflow Routing
When executing a workflow, output this notification directly:
Running the **WorkflowName** workflow from the **Android** skill...
| Workflow | Trigger | File |
|---|---|---|
| GomobileBind | "build go library for android", "create AAR", "gomobile bind" | workflows/GomobileBind.md |
| GomobileApp | "build android app with go", "gomobile build", "standalone go app" | workflows/GomobileApp.md |
| Setup | "setup android dev", "install android sdk", "android environment" | workflows/Setup.md |
| Build | "build apk", "build aab", "gradle build", "assemble" | workflows/Build.md |
| Debug | "debug android", "adb logcat", "android logs", "troubleshoot app" | workflows/Debug.md |
| Emulator | "android emulator", "avd", "virtual device", "start emulator" | workflows/Emulator.md |
| Gradle | "gradle dependencies", "build.gradle", "android dependencies" | workflows/Gradle.md |
| Publish | "publish to play store", "sign apk", "release build", "keystore" | workflows/Publish.md |
| Test | "android tests", "instrumentation", "ui tests", "espresso" | workflows/Test.md |
| Nix | "android on nix", "nixpkgs android", "android sdk nix" | workflows/Nix.md |
Core Principles
- Gomobile for Go integration: Use
gomobile bindfor libraries,gomobile buildfor standalone apps - Modern Gradle: Prefer Kotlin DSL (
.gradle.kts) over Groovy - Version catalogs: Centralize dependency versions in
libs.versions.toml - Multi-architecture: Support arm64-v8a, armeabi-v7a, x86_64, x86
- Type safety: Handle Go ↔ Java/Kotlin type conversions carefully
- SDK tools: Use
sdkmanagerandavdmanagerfor command-line management - Reproducible builds: Lock dependency versions and use consistent tooling
Android Project Structure
Standard Android Project
myapp/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/com/example/myapp/
│ │ │ │ └── MainActivity.kt
│ │ │ ├── res/
│ │ │ │ ├── layout/
│ │ │ │ ├── values/
│ │ │ │ └── drawable/
│ │ │ └── AndroidManifest.xml
│ │ ├── test/ # Unit tests
│ │ └── androidTest/ # Instrumentation tests
│ ├── build.gradle.kts
│ └── proguard-rules.pro
├── gradle/
│ └── libs.versions.toml # Version catalog
├── build.gradle.kts # Root build file
├── settings.gradle.kts # Project settings
├── gradle.properties
└── local.properties # SDK location (not in git)
Android Project with Gomobile
myapp/
├── app/
│ ├── libs/
│ │ └── mylib.aar # Generated by gomobile bind
│ ├── src/main/
│ │ ├── java/
│ │ └── AndroidManifest.xml
│ └── build.gradle.kts
├── golib/ # Go library source
│ ├── mylib.go
│ └── go.mod
├── build-aar.sh # Script to build AAR with gomobile
└── gradle/
Gomobile Overview
What is Gomobile?
Gomobile enables Go code to run on Android (and iOS). Two main modes:
gomobile bind: Create native library (AAR) from Go package
- Go code becomes Android library
- Called from Java/Kotlin
- Best for integrating Go into existing Android apps
gomobile build: Create standalone Android app
- Entire app written in Go
- Uses gomobile app package
- Limited Android UI capabilities
Type Mapping (Go ↔ Java/Kotlin)
| Go Type | Java Type | Kotlin Type | Notes |
|---|---|---|---|
bool |
boolean |
Boolean |
|
int, int32 |
int |
Int |
32-bit |
int64 |
long |
Long |
64-bit |
float32 |
float |
Float |
|
float64 |
double |
Double |
|
string |
String |
String |
|
[]byte |
byte[] |
ByteArray |
|
error |
Exception |
Exception |
Becomes checked exception |
interface |
interface |
interface |
Must have exported methods |
struct |
class |
class |
Exported fields become getters/setters |
Gomobile Limitations
What works:
- Exported functions and methods
- Basic types (int, string, float, bool)
- Slices of basic types
- Interfaces with exported methods
- Structs with exported fields
- Callbacks via interfaces
What doesn't work:
- Generic types (Go 1.18+ generics)
- Maps (use structs or custom types)
- Channels (use callbacks instead)
- Unexported types/functions
- Complex nested types
- Variadic functions
Android SDK Management
SDK Structure
$ANDROID_HOME/
├── build-tools/
│ └── 34.0.0/ # Build tools version
├── cmdline-tools/
│ └── latest/
│ └── bin/
│ ├── sdkmanager
│ └── avdmanager
├── emulator/ # Android Emulator
├── ndk/
│ └── 26.1.10909125/ # NDK version
├── platform-tools/ # adb, fastboot
└── platforms/
└── android-34/ # API level 34
Essential Tools
- sdkmanager: Install and update SDK packages
- avdmanager: Create and manage Android Virtual Devices (AVDs)
- adb: Android Debug Bridge (device communication)
- emulator: Run Android Virtual Devices
- gradle: Build system
Gradle Configuration
Version Catalog (gradle/libs.versions.toml)
[versions]
agp = "8.3.0" # Android Gradle Plugin
kotlin = "1.9.22"
compileSdk = "34"
minSdk = "24"
targetSdk = "34"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version = "1.12.0" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version = "1.6.1" }
material = { group = "com.google.android.material", name = "material", version = "1.11.0" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
Root build.gradle.kts
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
}
App build.gradle.kts
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
}
android {
namespace = "com.example.myapp"
compileSdk = 34
defaultConfig {
applicationId = "com.example.myapp"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
// Add gomobile AAR
implementation(files("libs/mylib.aar"))
}
Testing
Test Types
Local Unit Tests (
src/test/)- Run on JVM
- Fast, no Android device needed
- Use JUnit, Mockito
Instrumentation Tests (
src/androidTest/)- Run on Android device/emulator
- Test Android framework APIs
- Use AndroidJUnit4, Espresso
UI Tests
- Test user interface
- Use Espresso, UI Automator
- Run on device/emulator
Example Unit Test
// src/test/java/com/example/myapp/CalculatorTest.kt
import org.junit.Test
import org.junit.Assert.*
class CalculatorTest {
@Test
fun addition_isCorrect() {
val calculator = Calculator()
assertEquals(4, calculator.add(2, 2))
}
}
Example Instrumentation Test
// src/androidTest/java/com/example/myapp/MainActivityTest.kt
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.rules.ActivityScenarioRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@get:Rule
val activityRule = ActivityScenarioRule(MainActivity::class.java)
@Test
fun testButtonClick() {
// Test implementation
}
}
Signing and Publishing
Debug Signing
Android Studio automatically creates debug keystore:
- Location:
~/.android/debug.keystore - Password:
android - Alias:
androiddebugkey
Release Signing
Create release keystore:
keytool -genkey -v \
-keystore release.keystore \
-alias myapp \
-keyalg RSA \
-keysize 2048 \
-validity 10000
Configure in app/build.gradle.kts:
android {
signingConfigs {
create("release") {
storeFile = file("../release.keystore")
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = "myapp"
keyPassword = System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
}
}
}
Build Types
APK: Android Package (direct install)
./gradlew assembleRelease # Output: app/build/outputs/apk/release/app-release.apkAAB: Android App Bundle (Play Store)
./gradlew bundleRelease # Output: app/build/outputs/bundle/release/app-release.aab
Common Commands
Gradle
# Build debug APK
./gradlew assembleDebug
# Build release AAB
./gradlew bundleRelease
# Install on connected device
./gradlew installDebug
# Clean build
./gradlew clean
# List tasks
./gradlew tasks
# Check dependencies
./gradlew dependencies
ADB (Android Debug Bridge)
# List devices
adb devices
# Install APK
adb install app-debug.apk
# Uninstall app
adb uninstall com.example.myapp
# View logs
adb logcat
# View logs for specific app
adb logcat | grep com.example.myapp
# Clear app data
adb shell pm clear com.example.myapp
# Take screenshot
adb shell screencap /sdcard/screen.png
adb pull /sdcard/screen.png
# Get device properties
adb shell getprop
# Start activity
adb shell am start -n com.example.myapp/.MainActivity
Gomobile
# Install gomobile
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
# Build AAR for Android
gomobile bind -target=android -o mylib.aar ./golib
# Build AAR for specific architectures
gomobile bind -target=android/arm64,android/amd64 -o mylib.aar ./golib
# Build standalone Android app
gomobile build -target=android ./cmd/myapp
# Build with custom app ID
gomobile build -target=android -appid=com.example.myapp ./cmd/myapp
Nix Integration
This repository uses NixOS. Android SDK can be configured via:
Using nixpkgs Android SDK
{ pkgs, ... }:
{
home.packages = with pkgs; [
android-studio
android-tools # adb, fastboot
];
# Or use androidenv for more control
android-sdk = pkgs.androidenv.composeAndroidPackages {
platformVersions = [ "34" ];
buildToolsVersions = [ "34.0.0" ];
includeNDK = true;
ndkVersion = "26.1.10909125";
includeEmulator = true;
};
}
See workflows/Nix.md for detailed Nix integration.
Best Practices
General
- Use Kotlin over Java for new code
- Follow Material Design guidelines
- Support multiple screen sizes and orientations
- Handle configuration changes properly
- Use Android Architecture Components (ViewModel, LiveData, Room)
- Implement proper error handling
- Add crash reporting (Firebase Crashlytics, Sentry)
Gomobile Specific
- Keep Go API simple and flat
- Avoid complex nested types
- Use interfaces for callbacks
- Document type conversions
- Test Go code separately from Android integration
- Consider performance implications of crossing Go/Java boundary
- Use goroutines carefully (they don't map to Android threads)
Security
- Never commit keystores to version control
- Use environment variables for secrets
- Enable ProGuard/R8 for release builds
- Validate all user inputs
- Use HTTPS for network communication
- Store sensitive data in Android Keystore
- Follow OWASP Mobile Security guidelines
Performance
- Use build variants for different configurations
- Enable code shrinking and obfuscation
- Optimize images and resources
- Use vector drawables when possible
- Profile with Android Profiler
- Monitor memory usage
- Implement proper caching strategies
Resources
Official Documentation
Gomobile Resources
Tools
Best Practices
Examples
Example 1: Build Go library as Android AAR
User: "I have a Go package with networking code. How do I use it in my Android app?"
→ Invokes GomobileBind workflow
→ Checks gomobile installation
→ Generates AAR with `gomobile bind`
→ Shows how to add AAR to build.gradle.kts
→ Provides example of calling Go code from Kotlin
Example 2: Debug Android app crash
User: "My app crashes when I click the submit button. How do I debug this?"
→ Invokes Debug workflow
→ Shows how to use `adb logcat` to view crash logs
→ Helps filter logs for the specific app
→ Explains stack trace interpretation
→ Suggests debugging strategies (breakpoints, logging)
Example 3: Setup Android development on NixOS
User: "How do I set up Android development on my NixOS machine?"
→ Invokes Nix workflow
→ Shows nixpkgs Android SDK configuration
→ Explains how to compose Android packages with androidenv
→ Configures environment variables (ANDROID_HOME, PATH)
→ Verifies setup with adb and gradle commands
Philosophy: Android development should embrace modern tooling and practices. Gomobile provides a powerful bridge between Go's excellent concurrency and networking capabilities and Android's vast ecosystem. Use the right tool for each layer: Go for backend logic and performance-critical code, Kotlin for UI and Android framework integration.