Micro‐optimizaciones Sprint 3 - jcrinconv/MISW4203-2026-12-ing-sw-apps-moviles GitHub Wiki
Para las micro-optimizaciones, se realizó un análisis de la aplicación con Lint, el cual puede ver a continuación:
Antes: lint-result-debug-base.html
Despues: lint-result-debug.html
Basado en estas sugerencias, se realizaron las micro-optimizaciones listadas abajo. Si desea consultar los cambios en el código fuente, puede dirigirse al PR #104 Feature/microoptimizaciones 2.
Caso a optimizar: En RetrofitClient.kt, los tres servicios de API se recrean en cada acceso mediante reflexión (Cada acceso invoca retrofit.create() con reflexión interna):
val albumApiService: AlbumApiService get() = retrofit.create(AlbumApiService::class.java)
val musicianApiService: MusicianApiService get() = retrofit.create(MusicianApiService::class.java)
val collectorApiService: CollectorApiService get() = retrofit.create(CollectorApiService::class.java)
Optimización: Cachear cada instancia en una variable privada, recreándola solo cuando cambie la baseUrl. Esto elimina el costo de reflexión en cada llamada a la red.
Caso a optimizar: En AlbumDetailFragment.kt, cada vez que el observer emite un álbum, se destruyen y recrean todas las vistas de tracks sin reciclaje:
private fun renderTracks(tracks: List<Track>) {
binding.llTracksContainer.removeAllViews()
tracks.forEachIndexed { index, track ->
val trackView = layoutInflater.inflate(R.layout.item_track, ...)
binding.llTracksContainer.addView(trackView)
}
}
Optimización: Ya existe TrackAdapter (con ListAdapter + DiffUtil) que no está siendo usado aquí. Reemplazar el LinearLayout (llTracksContainer) por un RecyclerView conectado al TrackAdapter existente. DiffUtil solo actualizará los ítems que cambiaron, sin destruir y recrear toda la lista.
Caso a optimizar: En AlbumDetailFragment.kt y MusicianDetailFragment.kt, se instancian dos objetos SimpleDateFormat en cada invocación de formatDate(). Son objetos pesados (incluyen calendarios e información de locale internamente):
// Se ejecuta en cada llamada:
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
val outputFormat = SimpleDateFormat("MMM d, yyyy", Locale.forLanguageTag("es"))
Optimización: Mover ambas instancias al companion object de cada fragmento para que se creen una sola vez al cargar la clase. Usar Locale.ROOT para el formato de entrada (ISO 8601 es locale-independiente) para evitar además el warning de campo estático con Locale.getDefault().
Caso a optimizar: ic_search.xml declara un viewport de 512×510 unidades pero se renderiza en 24×24dp. Esta discrepancia obliga al sistema a procesar una cantidad de puntos de path mucho mayor de la necesaria:
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="510.78"
Optimización: Normalizar el viewport a 24×24 (o 100×100) reescalando los valores del pathData proporcionalmente. Esto reduce el trabajo del renderizador de vectores sin cambiar la apariencia visual.
Caso a optimizar: En fragment_album_list.xml, hay dos botones con layout_weight dentro de un LinearLayout que a su vez está dentro de un MaterialCardView dentro de un ConstraintLayout:
<LinearLayout android:orientation="horizontal">
<Button android:layout_weight="1" ... /> <!-- btnSortName -->
<Button android:layout_weight="1" ... /> <!-- btnSortDate -->
</LinearLayout>
Optimización: Reemplazar el LinearLayout con pesos por un ConstraintLayout con app:layout_constraintWidth_percent o cadenas (chains) horizontales. Evita el doble paso de medición que impone layout_weight.
Caso a optimizar: En fragment_album_detail.xml, el AppBarLayout declara android:background="@color/background", el mismo color definido como android:windowBackground en el tema de la app:
<!-- En themes.xml -->
<item name="android:windowBackground">@color/background</item>
<!-- En fragment_album_detail.xml -->
<com.google.android.material.appbar.AppBarLayout
android:background="@color/background">
Optimización: Eliminar android:background del AppBarLayout. El sistema ya pinta ese fondo una vez a través del tema; dibujarlo de nuevo es overdraw innecesario.
Caso a optimizar: Los siguientes recursos existen en el proyecto pero no están referenciados en el código ni en los layouts:
- Drawable: ic_arrow_back.xml, ic_back.xml, bg_cancel_button.xml
- Estilo: CircleImage (en themes.xml)
- Strings: textos hardcodeados en fragment_album_create.xml ("Hola mundo") y en TrackAssociateViewModel.kt (mensajes de validación en español directo en el código)
Optimización: Eliminar los recursos no referenciados para reducir el tamaño del APK. Mover los strings hardcodeados a strings.xml para centralizar los textos y facilitar futuras traducciones.