En aquest tema, aprendrem com optimitzar el rendiment de les aplicacions Android per assegurar-nos que funcionin de manera fluida i eficient. La optimització del rendiment és crucial per proporcionar una bona experiència d'usuari i per assegurar que l'aplicació consumeixi la menor quantitat de recursos possible.
Objectius del Tema
- Comprendre la importància de l'optimització del rendiment.
- Identificar i solucionar colls d'ampolla en el rendiment.
- Utilitzar eines per mesurar i millorar el rendiment de l'aplicació.
- Implementar pràctiques recomanades per optimitzar el rendiment.
Conceptes Clau
- Importància de l'Optimització del Rendiment
- Experiència d'Usuari: Una aplicació ràpida i fluida millora la satisfacció de l'usuari.
- Consum de Recursos: Reduir el consum de CPU, memòria i bateria.
- Retenció d'Usuaris: Aplicacions lentes poden provocar que els usuaris les abandonin.
- Identificació de Colls d'Ampolla
- Anàlisi de Rendiment: Utilitzar eines com Android Profiler per identificar problemes de rendiment.
- Monitorització de la Memòria: Identificar fuites de memòria i ús excessiu de memòria.
- Anàlisi de la CPU: Identificar tasques que consumeixen molta CPU.
- Eines per Mesurar el Rendiment
- Android Profiler: Eina integrada a Android Studio per monitoritzar l'ús de CPU, memòria, xarxa i energia.
- Systrace: Eina per analitzar el rendiment del sistema.
- LeakCanary: Biblioteca per detectar fuites de memòria.
- Pràctiques Recomanades per Optimitzar el Rendiment
- Evitar Operacions Pesades en el Fil Principal: Utilitzar AsyncTask, Thread, o altres mecanismes per executar operacions en segon pla.
- Optimització de la Interfície d'Usuari: Reduir la complexitat dels dissenys, utilitzar ViewHolder en RecyclerView, etc.
- Gestió Eficient de la Memòria: Evitar fuites de memòria, utilitzar objectes lleugers, etc.
- Reduir el Consum de Xarxa: Utilitzar tècniques de caché, comprimir dades, etc.
- Optimització de la Bateria: Minimitzar l'ús de sensors, evitar tasques innecessàries en segon pla, etc.
Exemples Pràctics
Exemple 1: Utilització d'Android Profiler
// Exemple de codi per monitoritzar l'ús de la CPU public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Simulació d'una operació pesada new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 1000000; i++) { // Operació pesada } } }).start(); } }
Explicació:
- Aquest codi crea una operació pesada en un fil separat per evitar bloquejar el fil principal.
- Utilitza Android Profiler per monitoritzar l'ús de la CPU mentre s'executa aquesta operació.
Exemple 2: Evitar Fuites de Memòria amb WeakReference
public class MyActivity extends AppCompatActivity { private static class MyHandler extends Handler { private final WeakReference<MyActivity> mActivity; MyHandler(MyActivity activity) { mActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { MyActivity activity = mActivity.get(); if (activity != null) { // Processar el missatge } } } private final MyHandler mHandler = new MyHandler(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
Explicació:
- Utilitza
WeakReference
per evitar fuites de memòria en manejar referències a l'activitat. - Això assegura que l'activitat pugui ser recollida pel garbage collector quan ja no sigui necessària.
Exercicis Pràctics
Exercici 1: Optimització de la Interfície d'Usuari
- Descripció: Optimitza un disseny complex reduint la profunditat de la jerarquia de vistes.
- Instruccions: Crea un disseny XML amb diverses vistes i optimitza'l utilitzant
ConstraintLayout
per reduir la complexitat.
Exercici 2: Reduir el Consum de Xarxa
- Descripció: Implementa una tècnica de caché per reduir el consum de xarxa.
- Instruccions: Utilitza una biblioteca com
Retrofit
iOkHttp
per implementar una caché de respostes HTTP.
Exercici 3: Detectar i Solucionar Fuites de Memòria
- Descripció: Utilitza
LeakCanary
per detectar fuites de memòria en una aplicació. - Instruccions: Integra
LeakCanary
en el teu projecte i soluciona qualsevol fuita de memòria detectada.
Solucions als Exercicis
Solució a l'Exercici 1
<!-- Disseny original amb LinearLayout --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Label 1"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Label 2"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Label 3"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Label 4"/> </LinearLayout> </LinearLayout> <!-- Disseny optimitzat amb ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/label1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Label 1" app:layout_constraintEnd_toStartOf="@+id/label2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/label2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Label 2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/label1" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/label3" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Label 3" app:layout_constraintEnd_toStartOf="@+id/label4" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/label1"/> <TextView android:id="@+id/label4" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Label 4" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/label3" app:layout_constraintTop_toBottomOf="@+id/label2"/> </androidx.constraintlayout.widget.ConstraintLayout>
Solució a l'Exercici 2
// Configuració de Retrofit amb caché OkHttpClient okHttpClient = new OkHttpClient.Builder() .cache(new Cache(getCacheDir(), 10 * 1024 * 1024)) // 10 MB de caché .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (isNetworkAvailable()) { request = request.newBuilder() .header("Cache-Control", "public, max-age=" + 60) .build(); } else { request = request.newBuilder() .header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24) .build(); } return chain.proceed(request); } }) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build();
Solució a l'Exercici 3
// Integració de LeakCanary public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); if (LeakCanary.isInAnalyzerProcess(this)) { return; } LeakCanary.install(this); } }
Conclusió
En aquesta secció, hem après la importància de l'optimització del rendiment en les aplicacions Android i hem explorat diverses tècniques i eines per identificar i solucionar problemes de rendiment. Implementar aquestes pràctiques recomanades no només millorarà l'experiència de l'usuari, sinó que també assegurarà que la teva aplicació funcioni de manera eficient i consumeixi menys recursos.
Curs d'Android Studio
Mòdul 1: Introducció a Android Studio
- Introducció a Android Studio
- Configuració d'Android Studio
- Comprensió de la Interfície d'Android Studio
- Creació del teu Primer Projecte Android
Mòdul 2: Desenvolupament Bàsic d'Android
- Comprensió de l'Estructura del Projecte Android
- Introducció als Dissenys XML
- Components Bàsics de la Interfície d'Usuari
- Introducció a les Activitats
- Executar la teva Aplicació en un Emulador
Mòdul 3: Desenvolupament Intermedi d'Android
- Introducció als Intents
- Treballar amb Fragments
- Gestió de l'Entrada de l'Usuari
- Ús de RecyclerView
- Xarxes en Android
Mòdul 4: Desenvolupament Avançat d'Android
- Persistència de Dades amb SQLite
- Ús de Room per a la Gestió de Bases de Dades
- Components Avançats de la Interfície d'Usuari
- Vistes Personalitzades i Canvas
- Treballar amb Tasques en Segon Pla
Mòdul 5: Desenvolupament Professional d'Android
- Implementació de l'Arquitectura MVVM
- Injecció de Dependències amb Dagger
- Proves Unitàries i Proves de la Interfície d'Usuari
- Publicació de la teva Aplicació a Google Play
- Optimització del Rendiment