Outcome focus: Defined a repeatable assistant workflow for Android teams that combines sliced prompts, repo instructions, Android skills, screenshots, atomic commits, tests, and GHAS gates into one controlled development loop.
coding assistantsandroidgithub copilotamazon qmobile engineering
The coding assistant did not fail because it could not write code.
It failed because it wrote too much code in too many places.
That is the pattern I trust least with AI-assisted app development. A reasonable prompt goes in: "add this settings screen." The assistant returns a screen, a ViewModel, a repository stub, a navigation change, string resources, a theme adjustment, a Gradle version bump, and one small manifest edit it decided was necessary. Some of it is good. Some of it is plausible. One line breaks the build.
The assistant looks productive while the diff becomes hard to review.
My own field experience has been more iOS, Xcode, and Unity than production Android. The failure mode transfers cleanly. Mobile apps are full of small boundaries that matter: manifests, signing, entitlement-like configuration, lifecycle, generated files, build scripts, navigation, asset catalogs or resources, previews, test targets, and platform-specific rules that are easy to disturb accidentally.
Android adds its own sharp edges: Gradle, Android Gradle Plugin versions, Compose state, previews, AndroidManifest.xml, resource merging, permissions, ProGuard/R8, emulator feedback, and a fast-moving best-practice surface.
So the useful question is not "can GitHub Copilot or Amazon Q Developer build Android features?"
Of course they can help.
The useful question is how to make their help land as small, reviewable, reversible changes.
The Current Android Shift#
The April 2026 Android tooling announcement is important because it moves agent work away from guessing.
Google introduced Android CLI, Android skills, and the Android Knowledge Base in Android CLI and skills: Build Android apps 3x faster using any agent. The headline speed claim is less interesting to me than the mechanism: give agents a lightweight programmatic interface to Android development, then ground them in official task instructions and current docs.
That matters because agents are weakest when they have to infer platform workflow from stale memory.
Android CLI now gives agents commands for setup, project creation, SDK management, device management, documentation search, layout inspection, screenshot capture, skill installation, and app deployment. The Android docs describe it as a command-line interface for building Android with any tool of your choice, with access to Android skills and the Android Knowledge Base.
The commands that change the assistant workflow are concrete:
android update
android init
android skills list --long
android skills find "edge-to-edge"
android skills add --skill=edge-to-edge
android docs search "Compose state hoisting"
android docs fetch kb://android/topic/performance/overview
android layout --output=hierarchy.json
android screen capture --output=ui.png --annotate
android run --apks=app/build/outputs/apk/debug/app-debug.apkThe Android skills docs are even more direct: skills are AI-optimized instructions that help tools and agents execute Android patterns that follow best practices. The public android/skills repository currently includes skills for Navigation 3, edge-to-edge, AGP 9 upgrade, XML-to-Compose migration, R8 analysis, Play Billing upgrade, and XR/Glimmer work.
That list is revealing. These are not generic "write better Compose" tips. The repo says Android skill development focuses on workflows where evaluations show LLMs underperform, not areas where they are already proficient.
That is exactly how teams should think about internal assistant guidance.
Do not write a skill for "be good." Write a skill for the migration, module boundary, release checklist, or failure mode the assistant keeps getting wrong.
The Community Reaction Is the Right Warning#
The community reaction around the Android CLI announcement had the expected split: excitement about giving agents docs and tools, skepticism that project scaffolding is not the hard part, frustration about Android build complexity, and concern that agentic development can create new classes of mistakes.
That split is healthy.
The marketing claim is speed. The operator concern is control.
One commenter framed android docs as the part they wanted everywhere because agents otherwise invent where to find docs or blindly search local files. Another was disappointed that the first skills felt more like setup and migration recipes than day-to-day app development. Both reactions can be true.
Android CLI and skills do not remove engineering judgment. They remove some guessing.
That is still valuable.
The Working Model#
The workflow I trust is:
The rule is boring because boring survives:
One chat, one change, one commit, one PR.
If the assistant cannot complete the change in a slice that can be verified independently, the task is still too big.
Do Not Feed It the PRD#
Specs are useful. Spec-dumping into a coding assistant is usually not.
A monolithic PRD contains product intent, edge cases, future ideas, nice-to-haves, terminology, unresolved decisions, and implementation guesses. A human can read that and ask what is in scope. An assistant often treats it as permission.
That is how a settings screen prompt turns into navigation rewrites, permission changes, theme churn, and a repository abstraction nobody asked for.
Keep the PRD for humans. Give the assistant a work order.
Task: Add a Compose scaffold for the NotificationSettings screen.
Scope:
- Create `feature-settings/src/main/java/.../NotificationSettingsScreen.kt`.
- Add stateless composables only.
- Include `@Preview` functions for enabled and disabled states.
- Use existing theme tokens.
Do not:
- Modify Gradle files.
- Modify AndroidManifest.xml.
- Add navigation wiring.
- Add repository calls.
- Add permissions.
- Add persistence.
Verification:
- `./gradlew :feature-settings:compileDebugKotlin`
- `./gradlew :feature-settings:testDebugUnitTest`
Return:
- Files changed.
- What changed.
- How to verify.That prompt is not magic. It is an operating boundary.
It tells the assistant what success looks like and what counts as misbehavior.
Build in Layers#
For Android and Compose, the order matters.
Start with skeleton UI. Ask for composables and previews. No wiring. No side effects. No repository calls. No navigation.
Then appearance. Spacing, typography, Material theme usage, content descriptions, touch targets, adaptive layout, loading and empty states. Assistants are genuinely useful here because they can iterate quickly on Modifier chains, previews, and visual density.
Then local interactivity. State hoisting, input validation, expand/collapse, selected tabs, error text, enabled/disabled buttons, rememberSaveable when the state should survive recreation.
Then business logic. ViewModel, repository calls, coroutine behavior, LaunchedEffect, navigation, paging, cache policy, offline behavior, and error paths.
That sequence aligns with Android architecture guidance. The architecture docs emphasize separation of concerns, UI driven from data models, single source of truth, and unidirectional data flow. They also warn against stuffing everything into an Activity. Assistants need those boundaries repeated because they love to make one giant file that "works."
When the assistant jumps layers, stop it.
Refactor only. No behavior changes.
You mixed UI scaffolding, ViewModel state, and repository calls in one file.
Split the change into:
- `NotificationSettingsScreen.kt` for stateless UI.
- `NotificationSettingsUiState.kt` for state.
- `NotificationSettingsViewModel.kt` for state coordination.
Do not add repository calls yet.
Keep previews working with fake state.
Return only the refactor diff summary and verification commands.The phrase "no behavior changes" is not decoration. It protects the review.
Guardrails Belong in the Repository#
Prompt discipline helps one session. Repo instructions help every session.
GitHub's Copilot docs now describe three useful instruction surfaces: repository-wide custom instructions in .github/copilot-instructions.md, path-specific instructions in .github/instructions/*.instructions.md, and agent instructions through AGENTS.md. Copilot can use the nearest AGENTS.md in the directory tree, which makes nested module guidance possible.
Amazon Q Developer has a similar concept through project rules: Markdown files in .amazonq/rules are automatically used as project context in chat.
For an Android repo, I would keep AGENTS.md short and strict:
# Agent Rules
## Scope Control
- Make the smallest diff that satisfies the prompt.
- Do not modify `build.gradle*`, `settings.gradle*`, `gradle/libs.versions.toml`,
or `AndroidManifest.xml` unless the prompt explicitly names those files.
- Do not touch generated files, `build/`, signing configs, keystores, or API keys.
- Use `local.properties`, environment variables, or existing secret mechanisms for local config.
## Android Architecture
- Prefer Compose for new UI unless the module is explicitly View-based.
- Preserve module boundaries: UI in `feature-*`, shared UI in `core-ui`,
data access in `core-data`, network/database DTOs outside UI modules.
- Use unidirectional data flow: state down, events up.
- Keep repository calls out of composables.
- Keep side effects isolated in ViewModels or narrow effect handlers.
## Compose
- Add or update previews for new composables.
- Keep screen composables small; extract repeated sections.
- Provide content descriptions for meaningful icons and images.
- Do not introduce custom theme tokens without approval.
## Verification
- After changes, report the exact Gradle commands to run.
- For UI changes, include a screenshot or preview validation note.
- For repository or ViewModel changes, add or update tests.Mirror the same policy for Amazon Q:
When editing this Android project, follow the repo architecture and scope rules.
Do not edit Gradle, manifest, generated files, signing config, keystores, or
API-key handling unless the user explicitly requests that change.
Prefer small Compose UI slices with previews before wiring navigation, ViewModels,
repositories, coroutines, or permissions. Preserve module boundaries and report
the verification commands for every change.For Copilot, I would also add .github/copilot-instructions.md for repository-wide build and validation context, then path-specific instructions for high-risk areas:
---
applyTo: "**/*.gradle.kts,gradle/libs.versions.toml,settings.gradle.kts"
---
Gradle and version catalog edits are high-risk. Do not change plugin versions,
AGP versions, Kotlin versions, dependency coordinates, repositories, signing
configuration, or build types unless the task explicitly asks for build-system work.
When build files must change, explain why and run the narrowest relevant Gradle task.This is not over-management. It is how you stop the assistant from treating the build system as a suggestion box.
Use Android Skills Where They Fit#
Android skills are the newest piece I would actually adopt.
Use them for targeted workflows where Android has official moving parts:
edge-to-edge,navigation-3,agp-9-upgrade,migrate-xml-views-to-jetpack-compose,r8-analyzer,play-billing-library-version-upgrade.
I would not install every skill into every workflow by reflex. Install the ones that match the work. Keep the CLI updated with android update. Use android skills list --long before a migration. Use android docs search and android docs fetch when the assistant starts improvising around current APIs.
A good prompt now includes the skill explicitly:
Use the Android `edge-to-edge` skill if available.
Task: make the existing Account screen edge-to-edge.
Scope: only `feature-account` UI files and existing theme insets helpers.
Do not change navigation, Gradle, Manifest, or system bar colors globally.
Verify with a screenshot on a medium phone emulator.The official skill gives the assistant current Android guidance. Your prompt still gives it the blast radius.
Both are necessary.
Screenshots Beat Paragraphs#
Words stall out quickly on layout.
"Make this less cramped" is vague. "Match the screenshot: 24dp horizontal padding, align the card title with the avatar centerline, preserve theme spacing, no logic changes" is better.
Android CLI makes this more practical for agents. The android screen capture --annotate command can save a screenshot with labeled UI elements. The android layout --output=hierarchy.json command can return the active app's layout tree as JSON.
That changes the prompt from a paragraph into evidence:
Use the attached screenshot and `hierarchy.json`.
Task: fix vertical alignment in the profile header.
Scope: `ProfileHeader.kt` only.
Rules:
- No ViewModel changes.
- No navigation changes.
- Use existing spacing tokens.
- Preserve accessibility labels.
Target:
- Avatar and name baseline should align like the screenshot annotation.
- Primary button should remain at least 48dp high.Assistants are useful on this kind of repair. Give them a visible mismatch, a narrow file, and no permission to redesign the app.
Verification Is Part of the Prompt#
Do not ask the assistant to "update the screen" and then decide later how to test it.
Tell it the verification contract before it edits.
For a narrow UI scaffold:
./gradlew :feature-settings:compileDebugKotlin
./gradlew :feature-settings:testDebugUnitTestFor repository or ViewModel behavior:
./gradlew :feature-settings:testDebugUnitTestFor integration or UI flows:
./gradlew :app:connectedDebugAndroidTestFor full pull request confidence:
./gradlew assembleDebug testDebugUnitTest lintDebugYour repo may use Detekt, ktlint, screenshot tests, Paparazzi, Compose UI tests, or custom CI tasks. Put the actual commands in AGENTS.md and .github/copilot-instructions.md. Do not make each chat rediscover them.
Compose testing is not optional for critical behavior. The Android Compose testing docs call out APIs for finding elements, verifying attributes, and performing user actions. That is exactly the level of test an assistant can often generate well when the scope is small.
@Test
fun saveButton_isDisabledUntilNotificationTypeIsSelected() {
composeTestRule.setContent {
AppTheme {
NotificationSettingsScreen(
uiState = NotificationSettingsUiState(
emailEnabled = false,
pushEnabled = false,
),
onEmailChanged = {},
onPushChanged = {},
onSave = {},
)
}
}
composeTestRule
.onNodeWithText("Save")
.assertIsNotEnabled()
}The assistant can write this. The human still owns whether the test proves the right behavior.
Undo Is Git#
Do not trust an assistant's undo button as your recovery strategy.
Use atomic commits.
git switch -c codex/notification-settings-screen
git status --short
# prompt the assistant for one slice
./gradlew :feature-settings:compileDebugKotlin :feature-settings:testDebugUnitTest
git add feature-settings/src
git commit -m "Add notification settings scaffold"If the result is junk:
git restore --staged .
git restore .If you already committed it:
git revert <bad-commit-sha>Android Studio Local History is useful as a last-ditch recovery tool, but version control should be the primary undo model. One prompt, one commit is not ceremony. It is what keeps assistant speed from becoming review debt.
Enterprise Guardrails Are Not Optional#
If the repo is under enterprise controls, use them.
GitHub Advanced Security is relevant because coding assistants increase throughput and therefore increase the number of generated mistakes that can reach a PR. GitHub's GHAS docs group the important pieces clearly: code scanning and CodeQL for vulnerabilities, dependency review for vulnerable dependency changes, secret scanning and push protection for leaked credentials.
That matters for Android because assistants can accidentally:
- paste a token into a sample file,
- add a dependency with a known advisory,
- weaken a network-security config,
- introduce unsafe file handling,
- request a permission without product approval,
- add logging around sensitive user data,
- modify build scripts in a way CI does not expect.
Treat GHAS as part of the assistant workflow, not a security team afterthought.
The PR gate should include:
- build,
- unit tests,
- Compose or UI tests for critical flows,
- lint,
- Detekt or ktlint if your repo uses them,
- CodeQL or code scanning,
- secret scanning and push protection,
- dependency review for Gradle changes,
- human review for manifests, permissions, signing, network config, and dependency changes.
The assistant can generate code quickly. It cannot be the only reviewer of its own blast radius.
Do Not Accept Premature Features#
Assistants are generous in the worst way.
They will offer smart caching while you are placing buttons. They will suggest offline mode while you are validating a form. They will add animated transitions while the navigation contract is still undecided.
Do not argue with the idea. Capture it as backlog.
Good suggestion. Do not implement it in this change.
Add a TODO comment only if there is already an issue ID.
Continue with the current slice: local validation for the email field.Feature creep plus AI produces diffs that look impressive and cannot be reviewed meaningfully. The discipline is to land the slice you are on.
Reset Sessions Without Losing State#
Context windows fill. Assistant sessions drift.
Before starting a fresh chat, ask for a handoff note:
Create a handoff note for a fresh assistant session.
Include:
- Goal of the current feature.
- Files changed so far.
- Module boundaries touched.
- Decisions already made.
- Decisions still open.
- Commands that passed.
- Commands that still need to run.
- Explicit files the next assistant must not edit.
Keep it under 500 words.Paste that into the next session. It is cheaper than re-pasting the repo and safer than hoping the assistant remembers the important parts.
The Repeatable Pattern#
Here is the operating pattern I would teach a mobile team tomorrow.
Start with repo-level instructions. Add AGENTS.md, .github/copilot-instructions.md, path-specific .github/instructions/*.instructions.md, and .amazonq/rules/*.md if Amazon Q is in use. Keep them short. Name forbidden files. Name build commands. Name module boundaries.
Install Android CLI and initialize agent support with android init. Add Android skills only for the workflow you are running. Use android docs when the assistant is about to reason from stale Android memory.
Slice the work into one verifiable outcome. UI skeleton first. Appearance second. Local interactivity third. Business logic last.
Give the assistant focused artifacts: one composable, one preview, one failing test, one screenshot, one layout tree, one Gradle error. Not the whole PRD.
Run the narrowest meaningful verification after every slice. Commit only after verification. Revert immediately when the assistant strays.
Let GHAS and CI be part of the development loop, not a final ceremony.
What to Do Differently#
Coding assistants reward the engineer who can say no clearly.
No to monolithic prompts.
No to build-script edits unless the task is build-script work.
No to manifest changes without explicit approval.
No to generated files.
No to premature caching, offline mode, and surprise animations.
No to giant screen files that mix UI, state, repositories, and side effects.
The positive version is better:
Use current Android skills and docs. Keep assistant instructions in the repo. Feed narrow context. Work in layers. Use screenshots. Verify every slice. Commit atomically. Let security gates catch what speed misses.
That is how coding assistants become leverage instead of entropy.