DEV Community

Cover image for Android Dev Summit 2026: Google vuelve a reunir a los devs después de cuatro años y pone a los agentes en el centro de Android
Diego Ferreira Caetano
Diego Ferreira Caetano

Posted on Edited on

Android Dev Summit 2026: Google vuelve a reunir a los devs después de cuatro años y pone a los agentes en el centro de Android

Android Dev Summit 2026: Google vuelve a reunir a los devs después de cuatro años y pone a los agentes en el centro de Android

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-insights audita 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.

Mapa de madurez de los anuncios

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:

  1. Abre Settings > Tools > AI > Agents.
  2. Instala agentes desde el marketplace (Claude Agent, Codex, Antigravity…). Puedes tener varios y alternar.
  3. 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:

ACP te ayuda a construir; MCP deja que los agentes usen tu app


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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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-performance
  • android-profiler
  • r8-analyzer
  • play-policy-insights (audita código, manifest y SDKs contra las políticas de Play antes del envío)
  • android-intent-security y android-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:

Bucle de validación agéntica

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
Enter fullscreen mode Exit fullscreen mode

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.

El agente muestra, en semáforo, lo que falta antes del deploy

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
Enter fullscreen mode Exit fullscreen mode

2. Ejecútala con un prompt (este es el que sugiere Google):

Audit this app for Google Play policy compliance before I submit it.
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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.

Flujo del Migration Assistant

Paso a paso

  1. Instala el Android Studio Canary más reciente — la función está en ese canal.
  2. 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.
  3. 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í.
  4. Define el alcance con el agente. Te pregunta qué migrar ahora, qué queda en interoperabilidad y cómo tratar las vistas personalizadas.
  5. Revisa el plan. El agente arma un plan por etapas antes de tocar cualquier archivo.
  6. Conversión. El agente convierte el layout, el código de view binding y la lógica asociada en Compose idiomático.
  7. 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.
  8. Valida. Revisa los Compose Previews (o android preview en la terminal) y ejecuta Change Review con /review antes 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>
Enter fullscreen mode Exit fullscreen mode
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() }
    }
}
Enter fullscreen mode Exit fullscreen mode

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 = {})
}
Enter fullscreen mode Exit fullscreen mode

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() } }
        }
}
Enter fullscreen mode Exit fullscreen mode

Checklist para revisar lo que generó el agente

  • [ ] ¿El estado está elevado (Composable sin estado + un Route que recolecta el ViewModel)?
  • [ ] ¿Los textos usan stringResource en 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 @Composable sin UI y devuelve un State<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" }
Enter fullscreen mode Exit fullscreen mode

Ojo: todo módulo que llama a transform necesita buildFeatures { 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)
    }
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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.

Flujo de A2UI en Jetpack Compose

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")
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

Pantalla:

@Composable
fun AgenticUiScreen(viewModel: AgenticUiViewModel) {
    val surfaces by viewModel.a2uiSurfaces.collectAsStateWithLifecycle()
    Column(Modifier.fillMaxSize()) {
        surfaces.forEach { surface ->
            key(surface.id) { A2uiSurface(surfaceModel = surface) }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

Gemini Nano 4 y la ML Kit Agentic API

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")
}
Enter fullscreen mode Exit fullscreen mode
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()
Enter fullscreen mode Exit fullscreen mode

Límites que debes conocer:

  • maxTurns es 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+.

Cómo una función de tu app se vuelve una tool de Gemini

@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?,
)
Enter fullscreen mode Exit fullscreen mode

Fíjate en dos detalles:

  1. 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.
  2. 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
Enter fullscreen mode Exit fullscreen mode

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

Un código, muchas pantallas

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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

  1. 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.
  2. Calidad en CI (stable) — ejecuta android analyze sobre el AAB de release, guarda el JSON como artefacto y haz fallar el build si baja el puntaje de shrinking. Usa analyzeReleaseR8Config para atacar las 5 keep rules más costosas.
  3. Un ViewModel sin combine (alpha) — reescribe un ViewModel con 3+ fuentes usando transform y pruébalo con transformTest. Compara la legibilidad y verifica si se perdió algún evento.
  4. 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.
  5. 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

Este artículo también está disponible en portugués e inglés.

Top comments (0)