En esta guía, se incluyen las prácticas y la arquitectura recomendadas para desarrollar apps sólidas y de calidad.
Experiencias del usuario de apps para dispositivos móviles
Una app de Android típica consta de varios componentes de la app, como actividades, fragmentos, servicios, proveedores de contenido y receptores de emisión. A la mayoría de estos componentes los declaras en el manifiesto de la app. Luego, el SO Android usa ese archivo para decidir la integración de tu app a la experiencia del usuario general del dispositivo. Dado que una app para Android típica puede contener varios componentes y que los usuarios suelen interactuar con diferentes apps en poco tiempo, las apps deben adaptarse a distintos tipos de tareas y flujos de trabajo controlados por los usuarios.
Ten en cuenta que los dispositivos móviles tienen restricciones de recursos, de manera que, en cualquier momento, el sistema operativo podría cerrar algunos procesos de apps para hacer lugar para otros.
Según las condiciones de este entorno, es posible que los componentes de tu app se inicien de manera individual y desordenada, además de que el usuario o el sistema operativo podrían destruirlos en cualquier momento Debido a que no puedes controlar estos eventos, no debes almacenar ni mantener en la memoria ningún estado ni datos de la aplicación en los componentes de tu app, y estos elementos no deben ser interdependientes.
Principios comunes de arquitectura
Si se supone que no deberías usar los componentes de la aplicación para almacenar datos y estados, ¿cómo deberías diseñarla?
A medida que crece el tamaño de las apps para Android, es importante definir una arquitectura que permita que esta crezca, aumente su solidez y facilite su prueba.
La arquitectura de una app define los límites entre sus partes y las responsabilidades que debe tener cada una. A fin de satisfacer las necesidades que se mencionaron antes, debes diseñar la arquitectura de tu app para que cumpla con algunos principios específicos.
Separación de problemas
El principio más importante que debes seguir es el de separación de problemas.
Un error común es escribir todo tu código en una Activity
o un Fragment
. Estas clases basadas en IU solo deberían contener lógica que se ocupe de interacciones del sistema operativo y de IU. Si mantienes estas clases tan limpias como sea posible, puedes evitar muchos problemas relacionados con el ciclo de vida de los componentes y mejorar la capacidad de prueba de estas clases.
Ten en cuenta que las implementaciones de Activity
y Fragment
no son de tu propiedad, sino que estas solo son clases que representan el contrato entre el SO Android y tu app. El SO puede destruirlas en cualquier momento en función de las interacciones de usuarios y otras condiciones del sistema, como memoria insuficiente. Para brindar una experiencia del usuario satisfactoria y una experiencia de mantenimiento de apps más fácil de administrar, recomendamos que dependas en menor medida de esas apps.
Cómo controlar la IU a partir de modelos de datos
Otro principio importante es que debes controlar la IU a partir de modelos de datos, preferentemente que sean de persistencia. Los modelos de datos representan los datos de una app. Son independientes de los elementos de la IU y otros componentes de la app. Por lo tanto, no están vinculados a la IU ni al ciclo de vida de esos componentes, pero se destruirán cuando el SO decida quitar el proceso de la app de la memoria.
Los modelos de persistencia son ideales por los siguientes motivos:
Tus usuarios no perderán datos si el SO Android destruye tu app para liberar recursos.
Tu app continúa funcionando cuando una conexión de red es débil o no está disponible.
Si basas la arquitectura de tu app en clases de modelos de datos, mejorarás la capacidad de prueba y la solidez de tu app.
Única fuente de información
Cuando se define un nuevo tipo de datos en tu app, debes asignarle una Única fuente de información (SSOT, por sus siglas en inglés). La SSOT es la propietaria de esos datos, y solo SSOT puede modificarlos o mutarlos. Con ese fin, la SSOT expone los datos con un tipo inmutable y, para modificarlos, expone funciones o recibe eventos a los que otros tipos pueden llamar.
Este patrón trae varios beneficios:
- Centraliza todos los cambios en un tipo particular de datos en un solo lugar.
- Protege los datos para que otros tipos no puedan manipularlos.
- Hace que los cambios en los datos sean más rastreables. Por lo tanto, los errores son más fáciles de detectar.
En una aplicación que prioriza la condición sin conexión, la fuente de información de los datos de aplicación suele ser una base de datos. En otros casos, la fuente de información puede ser un ViewModel o incluso la IU.
Flujo de datos unidireccional
El principio de fuente de confianza única se suele usar en nuestras guías con el patrón de flujo de datos unidireccional (UDF). En este flujo, el estado fluye en una sola dirección. Los eventos que modifican los datos fluyen en la dirección opuesta.
En Android, el estado o los datos suelen fluir desde los tipos de jerarquía más altos a los de menor alcance. Por lo general, los eventos se activan desde los tipos de alcance inferior hasta que alcanzan la SSOT para el tipo de datos correspondiente. Por ejemplo, los datos de la aplicación generalmente fluyen desde las fuentes de datos hacia la IU. Los eventos del usuario, como presionar el botón, fluyen desde la IU hasta el SSOT, en donde los datos de la aplicación se modifican y se exponen en un tipo inmutable.
Este patrón garantiza mejor la coherencia de los datos, es menos propenso a errores, es más fácil de depurar y brinda todos los beneficios del patrón de SSOT.
Arquitectura de app recomendada
En esta sección, se muestra cómo estructurar la app según las prácticas recomendadas.
Teniendo en cuenta los principios de arquitectura comunes que se mencionaron en la sección anterior, cada aplicación debe tener al menos dos capas:
- La capa de la IU que muestra los datos de la aplicación en la pantalla.
- La capa de datos que contiene la lógica empresarial de tu aplicación y expone sus datos.
Puedes agregar una capa adicional llamada capa de dominio para simplificar y volver a utilizar las interacciones entre la IU y las capas de datos.

Arquitectura moderna de apps
Esta arquitectura moderna de apps promueve el uso de las siguientes técnicas, entre otras:
- Arquitectura en capas y reactiva
- Flujo unidireccional de datos (UDF) en todas las capas de la app
- Una capa de IU con contenedores de estado para administrar la complejidad de la IU
- Corrutinas y flujos
- Prácticas recomendadas para la inserción de dependencias
Para obtener más información, consulta las siguientes secciones, las otras páginas de la arquitectura en el índice y la página de recomendaciones que contiene un resumen de las prácticas recomendadas más importantes.
Capa de la IU
La función de la capa de la IU (o capa de presentación) consiste en mostrar los datos de la aplicación en la pantalla. Cuando los datos cambian, ya sea debido a la interacción del usuario (como cuando presiona un botón) o una entrada externa (como una respuesta de red), la IU debe actualizarse para reflejar los cambios.
La capa de la IU consta de los siguientes dos elementos:
- Elementos de la IU que renderizan los datos en la pantalla (puedes compilar estos elementos con las vistas o las funciones de Jetpack Compose)
- Contenedores de estados (como las clases ViewModel) que retienen datos, los exponen a la IU y controlan la lógica

Para obtener más información sobre esta capa, consulta la página sobre la capa de la IU.
Capa de datos
La capa de datos de una app contiene la lógica empresarial. Esta lógica es lo que le da valor a tu app. Además, está compuesta por reglas que determinan cómo tu app crea, almacena y cambia datos.
La capa de datos está formada por repositorios que pueden contener de cero a muchas fuentes de datos. Debes crear una clase de repositorio para cada tipo de datos diferente que administres en tu app. Por ejemplo, puedes crear una clase MoviesRepository
para datos relacionados con películas o una clase PaymentsRepository
para datos relacionados con pagos.

Las clases de repositorio son responsables de las siguientes tareas:
- Exponer datos al resto de la app
- Centralizar los cambios en los datos
- Resolver conflictos entre múltiples fuentes de datos
- Abstraer fuentes de datos del resto de la app
- Contener la lógica empresarial
Cada clase de fuente de datos debe tener la responsabilidad de trabajar con una sola fuente de datos, que puede ser un archivo, una fuente de red o una base de datos local. Las clases de fuente de datos son el puente entre la aplicación y el sistema para las operaciones de datos.
Para obtener más información sobre esta capa, consulta la página sobre la capa de datos.
Capa de dominio
La capa de dominio es una capa opcional que se ubica entre la capa de la IU y la de datos.
La capa de dominio es responsable de encapsular la lógica empresarial compleja o la lógica empresarial simple que varios ViewModels reutilizan. Esta capa es opcional porque no todas las apps tendrán estos requisitos. Solo debes usarla cuando sea necesario; por ejemplo, para administrar la complejidad o favorecer la reutilización.

Las clases de esta capa se denominan casos de uso o interactores. Cada caso de uso debe tener responsabilidad sobre una funcionalidad única. Por ejemplo, tu app podría tener una clase GetTimeZoneUseCase
si varios ViewModels dependen de las zonas horarias para mostrar el mensaje adecuado en la pantalla.
Para obtener más información sobre esta capa, consulta la página sobre la capa del dominio.
Cómo administrar dependencias entre componentes
Las clases de tu app dependen de otras para funcionar correctamente. Puedes usar cualquiera de los siguientes patrones de diseño para recopilar las dependencias de una clase en particular:
- Inserción de dependencia (DI): Permite que las clases definan sus dependencias sin construirlas. En el tiempo de ejecución, otra clase es responsable de proporcionar estas dependencias.
- Localizador de servicios: Su patrón brinda un registro en el que las clases pueden obtener sus dependencias en lugar de construirlas.
Estos patrones te permiten hacer un escalamiento del código, ya que proporcionan patrones claros para administrar dependencias sin duplicar el código ni aumentar la complejidad. Además, te permiten cambiar rápidamente entre las implementaciones de prueba y de producción.
Te recomendamos seguir los patrones de inserción de dependencia y usar la biblioteca Hilt en las apps para Android. Hilt construye automáticamente objetos con un recorrido del árbol de dependencias, proporciona garantías de tiempo de compilación sobre dependencias y crea contenedores de dependencias para clases de framework de Android.
Prácticas recomendadas generales
La programación es una disciplina creativa y crear apps de Android no es una excepción. Hay muchas maneras de resolver un problema: puedes comunicar datos entre varias actividades o fragmentos, recuperar datos remotos y conservarlos a nivel local para el modo sin conexión, o bien controlar cualquier cantidad de situaciones comunes con las que pueden encontrarse las apps no triviales.
Aunque las siguientes recomendaciones no son obligatorias, en la mayoría de los casos, si las sigues, tu código base será más confiable, tendrá mayor capacidad de prueba y será más fácil de mantener a largo plazo.
No almacenes datos en los componentes de la app
Evita designar los puntos de entrada de tu app (receptores de emisiones, servicios y actividades) como fuentes de datos. En cambio, solo deben coordinar con otros componentes para recuperar el subconjunto de datos relevante para ese punto de entrada. Cada componente de la app tiene una duración relativamente corta, según la interacción que el usuario tenga con su dispositivo y el estado general del sistema en ese momento.
Reduce las dependencias de clases de Android
Los componentes de tu app deben ser las únicas clases que dependan de las APIs del SDK del framework de Android, como Context
o Toast
. La abstracción de otras clases en tu app fuera de ellas ayuda con la capacidad de prueba y reduce el acoplamiento dentro de la app.
Crea límites de responsabilidad bien definidos entre varios módulos de tu app.
Por ejemplo, no extiendas el código que carga datos de la red entre varias clases o paquetes en tu código base. Del mismo modo, no definas varias responsabilidades no relacionadas, como caché de datos y vinculación de datos, en la misma clase. Podría ser útil que siguieras la arquitectura de la app recomendada.
Expón lo mínimo indispensable de cada módulo
Por ejemplo, no caigas en la tentación de crear un acceso directo que exponga un detalle interno de la implementación de un módulo. Quizás ahorres algo de tiempo a corto plazo, pero tendrás más probabilidades de que se generen problemas técnicos a medida que tu código base evolucione.
Concéntrate en aquello que hace única a tu app para que se destaque del resto
No desperdicies tu tiempo reinventando algo que ya existe ni escribiendo el mismo código estándar una y otra vez. En cambio, enfoca tu tiempo y tu energía en aquello que hace que tu app sea única y deja que tanto las bibliotecas de Jetpack como las otras recomendadas se ocupen del código estándar repetitivo.
Piensa en cómo lograr que cada parte de tu app se pueda probar por separado
Por ejemplo, una API bien definida para recuperar datos de la red facilitará las pruebas que realices en el módulo que conserve esa información en la base de datos local. En cambio, si combinas la lógica de estos dos módulos en un solo lugar, o bien si distribuyes el código de red por todo tu código base, será mucho más difícil (y quizás hasta imposible) ponerlo a prueba eficazmente.
Los tipos son responsables de su política de simultaneidad
Si un tipo realiza un trabajo de bloqueo de larga duración, debería ser responsable de mover ese cálculo al subproceso correcto. Ese tipo particular conoce el tipo de procesamiento que está haciendo y en qué subproceso debe ejecutarse. Los tipos deben ser seguros para el subproceso principal, lo que significa que son seguros llamarlos desde el subproceso principal sin bloquearlo.
Conserva la mayor cantidad posible de datos relevantes y actualizados
De esa manera, los usuarios podrán aprovechar la funcionalidad de tu app, incluso cuando su dispositivo esté en modo sin conexión. Recuerda que no todos tus usuarios cuentan con una conexión de alta velocidad de manera constante y, si lo hacen, pueden tener una mala recepción en lugares muy concurridos.
Beneficios de la arquitectura
Tener una buena arquitectura implementada en tu app trae muchos beneficios a los equipos de proyectos y de ingeniería:
- Mejora la capacidad de mantenimiento, calidad y solidez de la app en general.
- Permite que la aplicación escale. Más personas y más equipos pueden contribuir a la misma base de código con conflictos de código mínimos.
- Ayuda con la integración. A medida que la arquitectura aporta coherencia a tu proyecto, los miembros nuevos del equipo pueden ponerse al día rápidamente y ser más eficientes en menos tiempo.
- Es más fácil probarlo. Una buena arquitectura fomenta tipos más simples que, en general, son más fáciles de probar.
- Los errores se pueden investigar metódicamente con procesos bien definidos.
Invertir en arquitectura también tiene un impacto directo en tus usuarios, ya que se beneficiarán de una aplicación más estable y de más funciones gracias a un equipo de ingeniería más productivo. Sin embargo, la arquitectura también requiere una inversión de tiempo inicial. Para ayudarte a justificar este tiempo al resto de tu empresa, revisa estos casos de éxito en los que otras empresas comparten sus historias de éxito cuando tienen una buena arquitectura en su app.
Ejemplos
En los siguientes ejemplos de Google, se demuestra una buena arquitectura de la app. Explóralos para ver esta guía en práctica:
Mir 2: Return of the King es un juego para dispositivos móviles de alta calidad con la IP de Legend autorizado por Actoz Soft y desarrollado por HK ZHILI YAOAN LIMITED con el motor de juego Unity. Este juego no solo recrea a la perfección los Wuthering Waves es un juego de rol de acción de alta fidelidad desarrollado por Kuro Games.
Optimizar el consumo de energía es muy importante para ofrecer de forma sostenible una experiencia del usuario premium en sesiones de juego largas. Android Godot Engine es un popular motor de juego multiplataforma de código abierto con una compatibilidad sólida con Android. Godot se puede usar para crear juegos de prácticamente cualquier género y es capaz de renderizar gráficos en 2D y 3D. La versión 4 El framework de rendimiento dinámico (ADPF) de Android es una herramienta potente de Google para desarrolladores que desean optimizar el rendimiento de sus aplicaciones. A través de sus APIs térmicas, ADPF proporciona información en tiempo real sobre NCSoft Lineage W es un juego de rol multijugador masivo en línea (MMORPG) desarrollado por NCSoft. Este juego hereda el legado del juego original de Lineage W y ofrece un entorno en el que los jugadores de todo el mundo pueden cooperar y competir a La mejora del rendimiento y la administración térmica es fundamental para desarrollar juegos exitosos en Android. Tradicionalmente, los desarrolladores tenían que manejar estos problemas disminuyendo la fidelidad del juego o optimizando aún más el Call of Duty: Warzone Mobile es un juego de acción en primera persona de la popular franquicia Call of Duty. La materialización móvil del juego de consola y de PC, que es muy popular, aprovecha las APIs de bajo nivel para dispositivos móviles con el Summoners War: Chronicles es un MMORPG para dispositivos móviles del desarrollador de juegos surcoreano Com2uS que se lanzó a nivel mundial en marzo de 2023. Hasta la fecha, Summoners War ha ganado más de USD 2,700 millones con más de 180 millones de Summoners War: Chronicles US(WW) y KR de Com2uS usan exclusivamente Vulkan para la renderización en Android, con mejoras de rendimiento de hasta un 30%. Vulkan es una API multiplataforma moderna de gráficos 3D diseñada para minimizar la abstracción Ares: Rise of Guardians es un MMORPG de ciencia ficción de dispositivo móvil a PC desarrollado por Second Dive, un estudio de juegos con sede en Corea, conocido por su experiencia en el desarrollo de series de RPG de acción. Kakao Games publicó el Cat Daddy Games es un estudio de propiedad plena de 2K con sede en Kirkland, Washington y el desarrollador de NBA 2K Mobile.
El equipo quería mejorar la calidad y estabilidad generales de sus juegos, en particular, reduciendo los errores de Devsisters es un desarrollador y publicador de juegos para dispositivos móviles a nivel mundial que produce juegos casuales basados en la IP de Cookie Run. Sus juegos más populares incluyen Cookie Run: OvenBreak (salada de videojuegos para correr) y NEW STATE Mobile es un juego de batalla masiva de Krafton que se lanzó en noviembre de 2021 en todo el mundo y alcanzó más de 45 millones de descargas en el primer mes de su lanzamiento. KRAFTON, Inc. es un colectivo de estudios independientes de Con sede en Polonia, Spokko es un grupo de creadores ambiciosos que trabajan con IP muy exigentes. Aunque forma parte de la familia CD PROJEKT, Spokko es una empresa independiente que trasladó el gran mundo de The Witcher: Monster Slayer a los Cat Daddy Games es un estudio de propiedad plena 2K con sede en Kirkland, Washington. Los equipos detrás de las series NBA 2K Mobile, NBA SuperCard y WWE SuperCard buscaban una solución con el fin de mejorar la calidad general de sus juegos para los Unreal Engine es un motor de juego desarrollado por Epic Games, que brinda a los creadores de todas las industrias libertad y control para ofrecer entretenimiento de vanguardia, visualizaciones atractivas y mundos virtuales envolventes. Algunos Electronic Arts (EA) es una empresa de juegos con sede en California, EE.UU. Produce una gran variedad de juegos de diferentes géneros, como deportes, acción, carreras y simulación. El estudio de desarrollo de EA, Firemonkeys, es más conocido como el Con sede en Varsovia, Polonia, la empresa desarrolladora de juegos CD Projekt RED (CDPR) rediseñó su minijuego de The Witcher 3, GWENT: The Witcher Card Game, para lanzarlo como título independiente y gratuito en Google Play en marzo de 2020.
Debido La empresa desarrolladora RV AppStudios, cuya sede está en EE.UU., cuenta con más de 200 millones de descargas hasta la fecha de los juegos casuales, las apps educativas para niños y las apps de utilidad que conforman su cartera. Siendo uno de los En el año 2000, Gameloft se creó gracias a la pasión por los juegos y un deseo de llevarlos a los jugadores de todo el mundo. Fue pionera en el desarrollo de apps para dispositivos móviles y ahora tiene una cartera de más de 190 juegos. Muchos de los Durante más de 20 años, Gameloft ha creado experiencias de juego innovadoras para plataformas digitales, desde juegos para dispositivos móviles hasta títulos multiplataforma de PC y consola. Además de sus propias franquicias establecidas, Gameloft El equipo de desarrolladores de videojuegos con sede en Moscú, Pixonic, se enorgullece de aprovechar todas las oportunidades para actualizar las apps para dispositivos móviles y llegar a un público más amplio de gamers. Uno de los títulos más Gameloft siempre se esfuerza por ser uno de los primeros desarrolladores en publicar juegos en el hardware portátil más reciente para brindarles a los gamers experiencias emocionantes dondequiera que estén. Por eso, Gameloft sabía que ChromeOS era elMir 2 mejora el rendimiento de renderización con la biblioteca de Frame Pacing.
Kuro Games reduce el consumo de energía en un 9.68% con el generador de perfiles de energía de Android Studio y ODPM para Wuthering Waves
Optimización de Vulkan de Godot Engine para Android
Cómo comenzar a usar el Framework de rendimiento dinámico de Android (ADPF) en Unreal Engine
NCSoft Lineage W mejora el rendimiento sostenido y previene los límites térmicos mediante el uso de ADPF
MediaTek mejora el rendimiento dinámico de los SoCs de Android
Call of Duty Warzone Mobile usa Vulkan para mejorar los gráficos
Com2uS - Google Play Juegos para PC
Com2uS usa Vulkan para obtener mejores gráficos
Kakao Games aumentó la estabilidad de FPS en un 96% gracias a la adaptabilidad para Android
2K reduce la tasa de ANR en un 35% con Android Game Development Kit
Cookie Run: OvenBreak ahorra más de USD 200,000 en costos de CDN con Play Asset Delivery
NEW STATE para dispositivos móviles reduce el uso de GPU en un 22% con el Inspector de GPU de Android
The Witcher: Monster Slayer mejora su alcance con Android Performance Tuner
2K entrega gráficos de mayor calidad con Play Asset Delivery
"AGDE es increíble" para el desarrollo de Android con Unreal Engine
Firemonkeys redujo el tiempo de desarrollo y depuración con AGDE
CD Projekt RED: Reduce el tamaño de las actualizaciones en un 90% y aumenta las tasas de actualización en un 10% con Play Asset Delivery
RV AppStudios mejora la retención de usuarios con Google Play Asset Delivery
Gameloft adquiere un 10% más de usuarios nuevos con Google Play Asset Delivery
Gameloft reduce el consumo de energía de los dispositivos en un 70%, lo que aumenta el tiempo de juego en un 35% con la API de Game Mode
Pixonic aumentó la participación en un 25% en ChromeOS mediante la optimización para pantallas grandes
Gameloft obtiene 9 veces más ingresos gracias a la optimización para ChromeOS
En estos momentos, no hay ninguna recomendación.
Prueba a iniciar sesión en tu cuenta de Google.