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
WeakReferenceper 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
ConstraintLayoutper 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
RetrofitiOkHttpper implementar una caché de respostes HTTP.
Exercici 3: Detectar i Solucionar Fuites de Memòria
- Descripció: Utilitza
LeakCanaryper detectar fuites de memòria en una aplicació. - Instruccions: Integra
LeakCanaryen 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
