Mountain View, 28 de octubre de 2026 — Después de cuatro años sin un evento propio, Google volvió a realizar el Android Dev Summit. La última edición había sido en 2022; desde entonces, las novedades de la plataforma compartían espacio con el resto del Google I/O. Esta vez fueron dos días dedicados solo a Android, en el campus Bay View, con el keynote transmitido en YouTube y una edición extendida en Londres.
El mensaje del keynote fue directo: Android ahora se construye con agentes de IA y para agentes de IA. Android Studio abrió sus puertas a agentes de otras empresas, como Claude y Codex. Android CLI les dio a esos agentes acceso a dispositivos reales. Y las apps ganaron una forma estándar de ofrecer sus funciones a Gemini.
En este briefing reúno lo que se anunció, en qué etapa está cada novedad y — la parte que el keynote recorre rápido — cómo usar cada una en el día a día, con código.
Ficha del evento
| Cuándo | 28 y 29 de octubre de 2026 |
| Dónde | Campus Bay View de Google, Mountain View (EE. UU.), con edición extendida en Londres |
| Contexto | Primer Android Dev Summit desde 2022 |
| Tracks | AI experiences, Android XR, Apps foundation, Tools & performance |
| Keynote | Cerca de una hora, con demos en vivo — míralo en YouTube |
Los titulares
- Android Studio Rabbit 2 llega a stable y acepta cualquier agente de código compatible con ACP — Claude, Codex, Antigravity y más de 40 otros.
- Android CLI suma dispositivos físicos remotos, render de Compose Preview en la terminal, un profiler con LeakCanary y plugins oficiales para Claude Code y Codex.
-
Checklist de publicación en semáforo: la skill
play-policy-insightsaudita la app antes del envío a Google Play y marca 🟢🟡🔴 lo que falta. - Migración de XML a Compose con un clic derecho, guiada por un agente dentro de Android Studio.
- AppFunctions pasa a beta: las funciones de tu app se vuelven tools para Gemini y otros agentes, vía Android MCP.
- A2UI (alpha): los agentes ahora pueden responder con pantallas nativas en Compose, hechas con tu design system.
- Gemini Nano 4 + ML Kit Agentic API (alpha): un agente completo corriendo en el dispositivo, con llamada de funciones.
- Jetpack AppState (alpha) lleva el modelo de estado de Compose a ViewModels y repositorios.
- Googlebook, plegables y Android XR: un código para muchas pantallas. XREAL AURA debuta como las primeras gafas XR con cable que corren Android XR.
1. Lo que ya puedes usar (y lo que todavía es laboratorio)
Antes de instalar todo, conviene mirar la madurez de cada anuncio.
Mi regla práctica: stable va a producción, beta entra detrás de un feature flag, alpha y preview se quedan en POC y estudio.
2. Android Studio Rabbit 2: trae tu propio agente
Android Studio dejó de ser "el IDE con Gemini". Con Bring Your Own Agent (BYOA), ahora stable en Rabbit 2, se convierte en el host de cualquier agente compatible con el Agent Client Protocol (ACP).
Cómo activarlo:
- Abre Settings > Tools > AI > Agents.
- Instala agentes desde el marketplace (Claude Agent, Codex, Antigravity…). Puedes tener varios y alternar.
- El agente pasa a ver lo que solo el IDE sabe: estructura del proyecto y del build, resolución de símbolos, render de Compose Preview, el Emulator y Logcat.
Además llegaron tres funciones que cambian el día a día:
-
Change Review — revisión agéntica de los cambios que hizo el agente. Inícialo desde los cambios pendientes, la ventana de Git o con
/review. Genera un reporte de problemas y un recorrido guiado para cambios grandes. - Migration Assistant (Canary) — clic derecho en un layout XML > AI › Migrate to Compose y el agente migra la pantalla a Compose. Más abajo hay una sección completa sobre esto.
- Android Bench 2.0 — un leaderboard que evalúa modelos y harnesses en tareas Android largas (migrar UI, construir una app desde mocks), midiendo si realmente funciona, además de costo y tiempo. Ideal para elegir el agente del equipo: developer.android.com/bench.
ACP vs MCP: no los confundas
Es el punto que más confusión genera. Son dos protocolos con funciones distintas:
3. Android CLI: todo el toolchain en manos del agente
Android CLI es la interfaz "tool-first" para cualquier terminal, agente o pipeline de CI. La idea es simple: el agente deja de gastar tokens adivinando cómo funciona Android y usa herramientas oficiales.
# instala el CLI y configura el agente
android init
# un dispositivo físico real, en un device lab de Google (vía Firebase)
android device remote connect
android device hub # ventana para ver y controlar dispositivos y emuladores
# Compose Previews sin emulador ni IDE
android preview
# rendimiento y memoria
android profiler systemtrace
android profiler heapdump capture
android profiler leakcanary
# calidad del binario y señales de producción
android analyze app-release.aab
android signals
# skills y documentación
android skills list
android skills add jetpack-compose-performance
android docs search "predictive back"
Los números que publicó Google llaman la atención: los agentes que usaron android preview terminaron tareas de UI 77% más rápido con hasta 3x menos tokens.
Plugins oficiales para Claude Code y Codex
# Claude Code (dentro de la sesión)
/plugin marketplace add android/android-cli-plugin
/plugin install android-cli@android-cli-plugin
# Claude Code (terminal)
claude plugin marketplace add android/android-cli-plugin
claude plugin install android-cli@android-cli-plugin
# Codex
codex plugin marketplace add android/android-cli-plugin
codex plugin add android-cli@android-cli-plugin
El plugin le da al agente lo necesario para crear proyectos, gestionar emuladores, inspeccionar layouts en vivo, ejecutar Journeys, instalar skills oficiales y consultar la Android Knowledge Base.
Skills oficiales
Son más de 30 skills en más de 20 áreas, cada una respaldada por evaluaciones. Apuntan a donde los modelos suelen fallar: rendimiento de Compose, APIs nuevas de cámara, auditorías de seguridad. Algunas que vale instalar ya:
jetpack-compose-performanceandroid-profilerr8-analyzer-
play-policy-insights(audita código, manifest y SDKs contra las políticas de Play antes del envío) -
android-intent-securityyandroid-permissions-security
Repositorio: github.com/android/skills.
4. Validación: el agente revisa su propio trabajo
El bloque "Validating apps with Android Prototype" del keynote (12:45) insiste en una idea: un buen agente verifica lo que hizo. La demo más memorable fue con Claude Code:
Google le dio al agente una lista de recorridos críticos y un único prompt — encontrar y corregir memory leaks. Claude ejecutó cada recorrido en un dispositivo distinto, en paralelo, usó android profiler leakcanary, siguió las cadenas de referencias hasta el código, lo corrigió y volvió a ejecutar todo para confirmar.
Lo que sostiene ese flujo:
- Journeys — flujos de usuario descritos en lenguaje natural. El equipo los escribe; el agente los ejecuta.
- LeakCanary integrado — en el CLI y en el Profiler de Studio, con Fix with AI (Canary).
-
Android Performance Analyzer (APA) — el motor del Profiler ahora también alimenta el CLI. Con la skill
android-profiler, el agente captura un trace, lo analiza, propone una corrección y mide el impacto. -
androidx.tracing 2.0 — traces con archivo, línea y argumentos; las coroutines aparecen como flujos conectados. Empieza con
androidx.tracing:tracing-wire. - Recomposition tracing (Compose 1.13) — muestra por qué algo se recompuso, hasta la escritura de estado que lo causó.
Del crash en producción a la corrección
android signals trae crashes, ANRs y problemas de memoria a la terminal. Y Crashlytics ahora recolecta heap dumps de OOMs reales y de Memory Limiter Kills de Android 17, desofuscados con el mapping de R8 y abiertos en Perfetto (early access).
R8 sin miedo
# AGP 9.3: puntaje de tu configuración y ranking de las keep rules más costosas
./gradlew :app:analyzeReleaseR8Config
Combínalo con la skill r8-analyzer y reemplaza keep rules genéricas por Jetpack Keep (alpha), anotaciones type-safe que lint puede agregar por ti.
5. Antes del deploy: el checklist en semáforo
Uno de los momentos más prácticos del evento: en lugar de un checklist manual de publicación, le pides al agente que audite la app y te devuelve un reporte en semáforo — 🟢 lo que está bien, 🟡 lo que necesita revisión, 🔴 lo que bloquea el envío.
La skill oficial: play-policy-insights
Ese formato viene de la skill oficial play-policy-insights, que audita tu código, manifest y SDKs contra las políticas de Google Play y lo cruza con tu declaración de Data safety.
1. Instala la skill
android skills add play-policy-insights
# alternativa, fuera de Android CLI:
npx skills add https://github.com/android/skills --skill play-policy-insights
2. Ejecútala con un prompt (este es el que sugiere Google):
Audit this app for Google Play policy compliance before I submit it.
3. Qué revisa
- Data safety — compara lo que tu código recolecta y transmite con lo que declaraste en Play Console.
- Credenciales de login de demostración — si los revisores de Play pueden entrar a la app.
- Permisos restringidos — permisos sensibles u obsoletos donde se espera una alternativa con alcance limitado.
4. Cómo leer el reporte
| Estado general | Significado | Qué hacer |
|---|---|---|
| 🟢 Compliant | No se encontraron violaciones activas | Seguir con el envío |
| 🟡 Needs Review | Sin violaciones críticas, pero hay declaraciones manuales en Play Console o permisos restringidos para revisar | Revisar antes de enviar |
| 🔴 Non-Compliant | Violaciones o diferencias en Data safety | Corregir antes del envío |
Cada hallazgo tiene severidad — 🔴 Critical (violación confirmada), 🟡 Important (por ejemplo, un permiso obsoleto donde se espera uno con alcance), 🔵 Suggestion (recomendación) — e incluye la política, los archivos afectados, la evidencia, un nivel de confianza, una recomendación y enlaces. El reporte termina con diferencias de Data safety, accesos locales a datos y un checklist de remediación.
Dos cuidados:
- El reporte es consultivo: no es asesoría legal ni garantía de aprobación.
- La skill escribe archivos temporales en
.scratch/play_policy_insights_<uuid>en la raíz del proyecto. Agrega.scratch/al.gitignore.
En Android Studio, Play Policy Insights también aparece como verificaciones de lint directamente en el código.
Más allá: una skill de "release readiness" con todos los gates
La política de Play es solo una de las puertas. Con las herramientas de Android CLI puedes escribir tu propia skill que ejecute todos los gates y devuelva un único semáforo. Este es un ejemplo que escribí para estudio — adapta rutas y umbrales a tu proyecto:
---
name: release-readiness
description: Úsala antes de publicar una release. Ejecuta los gates de build, tamaño, política de Play, seguridad, estabilidad y recorridos críticos y devuelve un reporte en semáforo.
---
# Release readiness
Ejecuta todos los gates de abajo, en orden. No te detengas en la primera falla: el reporte debe mostrar todos.
## Gates
1. **Build** — `./gradlew :app:bundleRelease`. 🔴 si falla.
2. **Tamaño y R8** — ejecuta `android analyze` sobre el AAB de release y `./gradlew :app:analyzeReleaseR8Config`.
🟡 si el puntaje de shrinking bajó respecto de `docs/release/last-analyze.json`. 🔴 si la ofuscación está desactivada.
3. **Política de Play** — ejecuta la skill `play-policy-insights` y copia su estado general.
4. **Seguridad** — ejecuta las skills `android-permissions-security` y `android-intent-security`. 🔴 ante cualquier hallazgo Critical.
5. **Estabilidad** — `android signals` para la versión actual en producción. 🟡 ante nuevos clusters de crash o ANR.
🔴 si los usuarios sin crash cayeron por debajo del umbral de `docs/release/thresholds.md`.
6. **Recorridos críticos** — ejecuta las Journeys de `journeys/`. 🔴 si alguna falla.
## Salida
Escribe `release-report.md` con:
- el estado general (el peor gate define el estado);
- una fila por gate: estado, gate, evidencia, próxima acción;
- un checklist de remediación.
No publiques, no subas nada y no crees tags. Publicar es una decisión humana.
En Claude Code, guárdala en .claude/skills/release-readiness/SKILL.md y llámala con /release-readiness. En otros agentes, usa su carpeta de skills equivalente. La regla "el peor gate define el estado" es lo que convierte seis verificaciones en un semáforo único y honesto.
6. Compose-first en la práctica: de XML a Compose con un clic derecho
Otro punto destacado del keynote: migrar una pantalla de XML Views a Jetpack Compose dejó de ser un proyecto manual. El Migration Assistant (Android Studio Canary) aparece en el menú contextual del layout y le delega el trabajo a un agente.
Paso a paso
- Instala el Android Studio Canary más reciente — la función está en ese canal.
-
Elige el agente. Funciona con el agente integrado de Studio o con cualquier agente agregado vía Bring Your Own Agent (Claude, Codex…). También conviene instalar la skill oficial Migrate to Compose, que aparece en
android skills list. -
Haz clic derecho en el layout XML (por ejemplo,
res/layout/fragment_profile.xml) y elige AI › Migrate to Compose. Para migrar todo el proyecto, abre la action palette y ejecuta la migración desde ahí. - Define el alcance con el agente. Te pregunta qué migrar ahora, qué queda en interoperabilidad y cómo tratar las vistas personalizadas.
- Revisa el plan. El agente arma un plan por etapas antes de tocar cualquier archivo.
- Conversión. El agente convierte el layout, el código de view binding y la lógica asociada en Compose idiomático.
- Sigue la timeline. La ventana del agente muestra qué etapa está corriendo y desde dónde retomar si se detiene. El progreso se guarda con la conversación: puedes irte y volver después.
-
Valida. Revisa los Compose Previews (o
android previewen la terminal) y ejecuta Change Review con/reviewantes del commit.
Ejemplo: lo que entra y lo que sale
Un ejemplo ilustrativo de este tipo de conversión — una pantalla de perfil con ViewBinding.
Antes (XML + ViewBinding):
<!-- res/layout/fragment_profile.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?attr/textAppearanceHeadlineSmall" />
<TextView
android:id="@+id/role"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/follow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/follow" />
</LinearLayout>
class ProfileFragment : Fragment(R.layout.fragment_profile) {
private val viewModel: ProfileViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val binding = FragmentProfileBinding.bind(view)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
binding.name.text = state.name
binding.role.text = state.role
binding.follow.isEnabled = !state.isFollowing
}
}
}
binding.follow.setOnClickListener { viewModel.follow() }
}
}
Después (Compose idiomático, con estado elevado):
@Composable
fun ProfileRoute(viewModel: ProfileViewModel = viewModel()) {
val state by viewModel.uiState.collectAsStateWithLifecycle()
ProfileScreen(state = state, onFollow = viewModel::follow)
}
@Composable
fun ProfileScreen(state: ProfileUiState, onFollow: () -> Unit, modifier: Modifier = Modifier) {
Column(modifier.padding(16.dp)) {
Text(state.name, style = MaterialTheme.typography.headlineSmall)
Text(state.role)
Button(onClick = onFollow, enabled = !state.isFollowing) {
Text(stringResource(R.string.follow))
}
}
}
@Preview
@Composable
private fun ProfileScreenPreview() {
ProfileScreen(ProfileUiState(name = "Ada", role = "Android Engineer"), onFollow = {})
}
Durante la transición, el Fragment puede seguir existiendo y solo alojar Compose:
class ProfileFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent { MaterialTheme { ProfileRoute() } }
}
}
Checklist para revisar lo que generó el agente
- [ ] ¿El estado está elevado (Composable sin estado + un Route que recolecta el ViewModel)?
- [ ] ¿Los textos usan
stringResourceen lugar de strings fijos? - [ ] ¿El tema del XML se mapeó a
MaterialTheme(colores, tipografía, formas)? - [ ] ¿Se preservó la accesibilidad:
contentDescription, tamaños táctiles, orden de lectura? - [ ] ¿Las pruebas de UI pasaron a
composeTestRule(o screenshot tests)? - [ ] ¿Sin recomposiciones innecesarias? Usa el recomposition tracing de Compose 1.13 y la skill
jetpack-compose-performance. - [ ] ¿Se eliminaron el XML y la clase de binding antiguos una vez estabilizada la pantalla?
Estrategia recomendada: migra pantalla por pantalla, empezando por las más simples o las que vas a tocar de todos modos, y usa ComposeView como puente. Migrar toda la app de una vez genera un diff imposible de revisar — incluso con un agente.
7. Compose-first: estado fuera de la UI con Jetpack AppState
Si alguna vez peleaste con un combine de cinco Flows, esto te va a gustar. Jetpack AppState (alpha) usa el runtime de Compose fuera de la UI, en ViewModels, repositorios y servicios. Son dos piezas:
-
Transform — ejecuta un bloque
@Composablesin UI y devuelve unState<R>que se recompone solo cuando cambia cualquier estado leído. - StateStore — un mapa type-safe de estado compartido entre activities, services y widgets, con persistencia opcional en DataStore.
[versions]
appstate = "1.0.0-alpha01"
[libraries]
androidx-appstate-transform = { module = "androidx.appstate.transform:transform", version.ref = "appstate" }
androidx-appstate-transform-testing = { module = "androidx.appstate.transform:transform-testing", version.ref = "appstate" }
androidx-appstate-statestore = { module = "androidx.appstate.statestore:statestore", version.ref = "appstate" }
Ojo: todo módulo que llama a
transformnecesitabuildFeatures { compose = true }y el plugin del Compose Compiler, aunque no tenga UI.
Un ViewModel que cambia de fuente según la conectividad:
class HomeViewModel(
private val mediaRepository: MediaRepository,
private val networkMonitor: NetworkMonitor,
) : ViewModel() {
val uiState: State<HomeUiState> = transform<HomeUiState>(
initialValue = HomeUiState.Loading,
scope = viewModelScope,
) {
val isOnline by networkMonitor.isOnline
val tracks = if (isOnline) {
mediaRepository.allTracksFlow.collectAsState(initial = null).value
} else {
mediaRepository.downloadedTracksFlow.collectAsState(initial = null).value
} ?: return@transform HomeUiState.Loading
HomeUiState.Success(tracks = tracks, isOnline = isOnline)
}
}
Sin flatMapLatest, sin stateIn: un if común decide qué fuente observar.
Debounce de búsqueda con LaunchedEffect, dentro de transform:
var query: String by mutableStateOf("")
val searchResults: List<String> by transform<List<String>>(
initialValue = emptyList(),
scope = coroutineScope,
) {
var results by remember { mutableStateOf(emptyList<String>()) }
LaunchedEffect(query) {
if (query.isBlank()) { results = emptyList(); return@LaunchedEffect }
delay(300.milliseconds)
results = api.search(query)
}
results
}
Cuándo NO usar transform: representa el valor actual, no un flujo de eventos. Las actualizaciones rápidas antes de la recomposición se descartan y los valores iguales consecutivos no disparan nada. Para totales acumulados, logs, eventos únicos y backpressure, sigue con Flow.
Las pruebas son simples con transformTest:
@Test
fun testStateUpdate() = transformTest {
var sourceState by mutableStateOf(0)
val state = transform(initialValue = 0, scope = backgroundScope, dispatcher = testDispatcher) {
sourceState
}
sourceState = 1
advance()
assertThat(state.value).isEqualTo(1)
}
Completan el paquete Compose 1.13 (stable pronto: Grid y FlexBox stable, Progressive Blur, Formatted Text) y Navigation 3 1.2 (stable: deep links y predictive back más rico). Ejemplos: github.com/android/appstate-recipes.
8. A2UI: cuando la respuesta del agente es una pantalla
Un muro de texto en un chat no es buena UX. Con A2UI (Agent-to-UI), el agente envía JSON declarativo y tu app renderiza componentes nativos de tu propio catálogo — sin ejecutar código arbitrario.
dependencies {
implementation("androidx.a2ui.compose:compose-runtime:1.0.0-alpha01")
implementation("androidx.a2ui.compose:compose-ui:1.0.0-alpha01")
androidTestImplementation("androidx.a2ui.compose:compose-ui-testing:1.0.0-alpha01")
}
ViewModel:
class AgenticUiViewModel : ViewModel() {
private val parser = A2uiMessageParser()
private val processor = A2uiMessageProcessor(catalogs = listOf(CustomDesignSystemCatalog))
val a2uiSurfaces: StateFlow<List<A2uiSurfaceModel>> = processor.activeSurfaces
init {
viewModelScope.launch(Dispatchers.Default) { processor.collectMessages() }
// clics y errores vuelven al agente
viewModelScope.launch(start = CoroutineStart.UNDISPATCHED) {
processor.outboundEvents.collect(::handleOutboundA2uiEvent)
}
}
fun onNetworkMessage(json: String) = processor.processInput(parser, json)
}
Pantalla:
@Composable
fun AgenticUiScreen(viewModel: AgenticUiViewModel) {
val surfaces by viewModel.a2uiSurfaces.collectAsStateWithLifecycle()
Column(Modifier.fillMaxSize()) {
surfaces.forEach { surface ->
key(surface.id) { A2uiSurface(surfaceModel = surface) }
}
}
}
Lo que más me gustó: las defensas contra alucinaciones vienen incluidas. Un componente desconocido se convierte en un error reportado al agente para que se corrija; el payload se valida contra un schema; los índices de lista absurdos pasan a un mapa disperso para no agotar la memoria.
9. Gemini Nano 4: un agente completo en el dispositivo
Gemini Nano 4 trajo function calling nativo, y ML Kit sumó una Agentic API (alpha) que ejecuta el bucle agéntico completo en el dispositivo, sobre AICore.
Requisitos: Android 14+ inscrito en el AICore Developer Preview, un dispositivo compatible, minSdk 26, Kotlin 2.3+.
dependencies {
implementation("com.google.mlkit:genai-agent:1.0.0-alpha1")
// opcional: tools vía AppFunctions
implementation("androidx.appfunctions:appfunctions:1.0.0-alpha13")
ksp("androidx.appfunctions:appfunctions-compiler:1.0.0-alpha13")
}
val agent = Agent.builder()
.setName("Assistant")
.setInstructions("You are a helpful on-device assistant.")
.build()
val runner = AgentRunner(agent)
val session = runner.getOrCreateSession("chat_session")
val prompt = Content.builder().text("Can you help me organize my day?").build()
lifecycleScope.launch {
session.runAsync(prompt)
.textTokens()
.collect { token -> Log.d("Agent", token) }
}
// sin historial: runner.runSingleTurnAsync(prompt)
// al destruir: runner.close()
Límites que debes conocer:
-
maxTurnses 10 por defecto, para evitar bucles infinitos y ahorrar batería. - La inferencia solo corre con la app en primer plano; demasiadas llamadas devuelven
ErrorCode.BUSY. - El modelo puede elegir la tool o el argumento equivocado: la seguridad de las acciones es responsabilidad de tu app. Confirma con el usuario las acciones sensibles.
- Para bases de conocimiento enormes, el propio Google recomienda una arquitectura híbrida con modelos en la nube.
10. Android MCP y AppFunctions: tu app como tool de Gemini
Para mí, este es el cambio más estratégico del evento. AppFunctions es el equivalente móvil de las tools de MCP: tu app se convierte en un servidor MCP on-device, y Gemini (u otro agente autorizado) descubre y llama a funciones de tu app para cumplir lo que pide el usuario. Está en beta y funciona en Android 16+.
@RequiresApi(36)
@AndroidEntryPoint
@AppFunctionServiceEntryPoint(
serviceName = "TaskAppFunctionService",
appFunctionXmlFileName = "task_app_function_service",
)
abstract class BaseTaskAppFunctionService : AppFunctionService() {
@Inject internal lateinit var taskRepository: TaskRepository
/**
* Creates a task based on [createTaskParams].
*
* @param createTaskParams The parameter to describe how to create the task.
*/
@AppFunction(isDescribedByKDoc = true)
suspend fun createTask(createTaskParams: CreateTaskParams): Task =
withContext(Dispatchers.IO) {
if (createTaskParams.title == null && createTaskParams.content == null) {
throw AppFunctionInvalidArgumentException("Title or content should be non-null")
}
val id = taskRepository.createTask(createTaskParams.title, createTaskParams.content)
taskRepository.getTask(id)?.toTask()
?: throw AppFunctionElementNotFoundException("Task not found for ID = $id")
}
}
/** The parameter to create the task. */
@AppFunctionSerializable(isDescribedByKDoc = true)
data class CreateTaskParams(
/** The title of the task. */ val title: String?,
/** The content of the task. */ val content: String?,
)
Fíjate en dos detalles:
-
El KDoc es el prompt. Con
isDescribedByKDoc = true, la documentación se convierte en la descripción que lee el agente para decidir cuándo llamar a la función. Escríbela pensando en el modelo. -
Las excepciones tipadas (
AppFunctionInvalidArgumentException,AppFunctionElementNotFoundException) le dicen al agente por qué falló, para que intente de otra manera.
Probando sin Gemini:
adb shell cmd app_function list-app-functions
AppFunctions vs servidor MCP remoto: AppFunctions corre localmente, usa el estado real de la app y no necesita backend. Un MCP remoto es agnóstico de plataforma y depende de la red. Los agentes consideran ambos juntos.
Para llegar a los usuarios, la Connected Apps Platform (preview) lleva los servicios de tu app a Gemini y a la Búsqueda: construyes con Android MCP o MCP remoto, prototipas en el Gemini dev mode y te registras en Google Connected Console.
⚠️ Realidad a oct/2026: la integración con Gemini todavía está limitada a apps seleccionadas. Puedes implementarla y probarla hoy; para producción hay un Early Access Program.
11. Un código, muchas pantallas: Googlebook, plegables y XR
Googlebook es la nueva categoría de laptops sobre una base Android, con socios como HP, Dell, Lenovo, Acer y Asus. La misma app corre en el teléfono y en la laptop, sin un código separado.
La Compose adaptive skill se actualizó para que el agente haga el trabajo pesado: atajos de teclado, cursores, hover y tooltips; migración a Grid, FlexBox y mediaQuery; manejo de estado de punta a punta; y posturas de plegables, como layouts tabletop para pantallas de multimedia y cámara.
📌 Aviso de Google Play: en 2027 Play revisará de cerca cómo corren las apps y los juegos en plegables. Sigue las adaptive app quality guidelines.
Android XR y XREAL AURA
XREAL AURA son las primeras gafas XR con cable que corren Android XR. Pesan menos de 95 g porque el procesamiento va en un "puck" con Snapdragon Reality Elite. Tienen pantalla Sony Micro-OLED 1200p a 120 Hz, ejecutan apps de Google Play y hasta cinco ventanas virtuales. Precio: US$ 1.099 de lanzamiento hasta diciembre (US$ 1.279 después), a la venta en Estados Unidos, Canadá, Japón y Corea del Sur.
Para los devs, lo más importante: el núcleo de Jetpack XR ya es stable (SceneCore, ARCore for Jetpack XR y XR Runtime), igual que los emuladores de gafas XR en Android Studio y el Android XR Engine Hub. Compose for XR sigue en alpha.
El primer paso es espacializar una pantalla que ya tienes:
Subspace {
SpatialPanel(
SubspaceModifier
.height(824.dp)
.width(1400.dp)
.resizable()
.transformingMovable(),
) {
MyExistingScreen() // tu pantalla Compose actual
}
}
El contenido dentro de Subspace solo se muestra cuando la espacialización está activa. En el teléfono se ignora, así que el mismo código sirve para ambos mundos.
12. Más allá del keynote: 5 laboratorios para esta semana
- Un agente con ojos y manos (stable) — instala Android CLI y el plugin en Claude Code o Codex, escribe 3 Journeys de tus flujos críticos y pide: "ejecuta los recorridos, captura un trace de inicio y propón la corrección de mayor impacto". Mide el cold start antes y después.
-
Calidad en CI (stable) — ejecuta
android analyzesobre el AAB de release, guarda el JSON como artefacto y haz fallar el build si baja el puntaje de shrinking. UsaanalyzeReleaseR8Configpara atacar las 5 keep rules más costosas. -
Un ViewModel sin
combine(alpha) — reescribe un ViewModel con 3+ fuentes usandotransformy pruébalo contransformTest. Compara la legibilidad y verifica si se perdió algún evento. -
Tu app como tool (beta) — usa la skill de AppFunctions para encontrar las 3 funciones de mayor valor, implementa una y valídala con
adb shell cmd app_function list-app-functions. - Una respuesta como UI (alpha) — arma un catálogo A2UI con 3 componentes de tu design system y aliméntalo con JSON fijo antes de conectar un modelo real. Prueba el camino de error.
Lo que deja el Dev Summit
El regreso del Android Dev Summit no estuvo marcado por una API aislada. Estuvo marcado por un cambio en el rol de quien desarrolla para Android: orquestar agentes que construyen, validan y optimizan la app — y diseñar la app para que la usen agentes.
Si quieres actuar ya, esta es mi lectura:
- Para adoptar hoy: Rabbit 2 con BYOA, Android CLI con skills, Change Review y el checklist en semáforo en el flujo del equipo.
- Este trimestre: migrar las pantallas XML que más se tocan, definir qué funciones de la app serán AppFunctions y preparar la UI adaptativa para plegables y Googlebook.
- En POC: A2UI, Gemini Nano 4 y AppState, siguiendo las APIs en su camino a stable.
¿Cuál de estas novedades vas a probar primero? Cuéntame en los comentarios. 👇
Fuentes
- Android Dev Summit 2026 keynote
- Agentic and Flexible: A next era of Android development
- What's new in Android developer tools and performance at Android Dev Summit
- Android skills (catálogo) y play-policy-insights
- Overview of AppFunctions
- Render A2UI surfaces in your app
- Build agentic workflows with Gemini Nano
- Jetpack AppState y Transform
- Develop UI with Jetpack Compose for XR
- TechCrunch — Xreal Aura
Este artículo también está disponible en portugués e inglés.










Top comments (0)