Disminuya el tamaño del APK (dentro de límites razonables)

Ya había un artículo similar en Habr.com que demostraba que puede reducir un archivo APK de 1,5 MB a 1757 bytes o menos. El propósito de este artículo es reducir el tamaño de la aplicación a un límite razonable, preservando su funcionalidad y resaltando algunas de las sutilezas y momentos implícitos.

Inicio


Cree un proyecto en Android Studio, seleccione Actividad vacía. Luego, en el archivo styles.xml, reemplace Activity con ActionBar

Theme.AppCompat.Light.DarkActionBar 

en Actividad sin ActionBar

 Theme.AppCompat.Light.NoActionBar 

El resultado:

imagen

En el analizador de APK vemos lo siguiente:



Por lo tanto, el APK pesa 1.5 MB, a pesar de que solo muestra las palabras "¡Hola Mundo!".

Etapa uno (minificación)


En el archivo build.gradle escribimos:

 android { buildTypes { debug { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro' } } } 

Sincronizaremos Android Studio para que los cambios surtan efecto.

Explicación

 minifyEnabled true 
eliminar código innecesario en la aplicación
 shrinkResources true 
eliminar recursos no utilizados de la APK.

El peso del APK se convirtió en 960 KB, sin cambios en el rendimiento.

Etapa dos (Agregar funcionalidad)


Para que la aplicación tenga sentido, agréguele funcionalidad, por ejemplo, un clicker.

Código Activity_main.xml
 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:textSize="20dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageButton android:id="@+id/imageButton" android:layout_width="90dp" android:layout_height="90dp" android:layout_marginBottom="32dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:background="#000000FF" android:cropToPadding="false" android:scaleType="fitXY" android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:srcCompat="@mipmap/ic_launcher_round" /> </android.support.constraint.ConstraintLayout> 


Código MainActivity.java
 import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; public class MainActivity extends AppCompatActivity { SharedPreferences Settings; ImageButton button; TextView text; int num = 31; View.OnTouchListener on = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { num--; if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",   "); } } return false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Settings = getSharedPreferences("settings", Context.MODE_PRIVATE); if (Settings.contains("left")) num = Settings.getInt("left", 0); button = findViewById(R.id.imageButton); button.setOnTouchListener(on); text = findViewById(R.id.number); if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",   "); } } @Override protected void onPause() { super.onPause(); SharedPreferences.Editor editor = Settings.edit(); editor.putInt("left", num); editor.apply(); } } 

La aplicación ha adquirido la siguiente forma:



Tamaño de la aplicación 1.1 MB, un aumento de 140 KB.

Etapa tres (elimine android.support y AppCompat)


Actualmente, el analizador de APK muestra lo siguiente:



public class MainActivity extends AppCompatActivity con la public class MainActivity extends Activity en MainActivity.java. Presione Alt + Entrar para que Android Studio importe las bibliotecas.

El tamaño de la aplicación no ha cambiado, pero ...



¿Dónde está el botón?

De hecho, todo está en orden, ella siguió siendo clicable. Pero ella simplemente no tiene una foto.

Vaya a activity_main.xml, encuentre la línea a continuación

 app:srcCompat="@mipmap/ic_launcher_round" 

y cambiarlo a

 android:src="@mipmap/ic_launcher_round" 

Ahora todo está bien:



Pero el tamaño no ha cambiado.

Volvemos a build.gradle y borramos el bloque de dependencia:

 dependencies { } 

Y sincronice Android Studio ... con errores.

1. Vaya al archivo res / values ​​/ styles.xml y reemplace todo su contenido con el siguiente código:

 <resources> <style name="AppTheme" parent="android:Theme.DeviceDefault.NoActionBar"> </style> </resources> 

2. ConstraintLayout, que se usa en Android Studio, depende de android.support, que ya se ha eliminado del bloque de dependencies , por lo que reemplazaremos ConstraintLayout con RelativeLayout, que no depende de android.support.

Código Activity_main.xml:
 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF"> <TextView android:id="@+id/number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="Hello World!" android:textSize="20dp" /> <ImageButton android:id="@+id/imageButton" android:layout_width="90dp" android:layout_height="90dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="32dp" android:background="#000000FF" android:scaleType="fitXY" android:src="@mipmap/ic_launcher_round" android:visibility="visible" /> </RelativeLayout> 


Compilamos el APK y vemos el resultado:



Nuestro APK pesa 202 KB, que es 7.5 veces más pequeño que su tamaño original.

La mayoría de los recursos están ocupados y nos ocuparemos de ellos.

1. Elimine los archivos en la carpeta res / drawable y borre la carpeta res / mipmap
2. Dibuje su icono y botón, luego reduzca su tamaño con ImageOptim.

Botón:



Ícono:



3. Descárguelos en Android Studio, para esto selecciónelos en la carpeta, presione Ctrl + C, vaya a Android Studio, seleccione la carpeta res / drawable y presione Ctrl + V, después de lo cual Andoid Studio ofrecerá varias opciones donde transferir las imágenes dependiendo de su permiso.

En la carpeta dibujable, puede cambiar el nombre del archivo seleccionando Refactorizar -> Cambiar nombre.
El ícono de la aplicación tiene el nombre i.png, la imagen del botón b.png

4. Ahora ve al archivo AndroidManifest.xml, líneas

 android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" 

reemplazar por

 android:icon="@drawable/i" android:roundIcon="@drawable/i" 

En el archivo activity_main.xml, reemplace el campo en ImageButton

 android:src="@mipmap/ic_launcher_round" 

en

 android:src="@drawable/b" 

Resumen


¡El tamaño total del archivo es 13.4 KB, que es 112 veces menor que el tamaño inicial!

Código final MainActivity.java
 import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; public class MainActivity extends Activity { SharedPreferences Settings; ImageButton button; TextView text; int num = 31; View.OnTouchListener on = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { num--; if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",   "); } } return false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.m); Settings = getSharedPreferences("settings", Context.MODE_PRIVATE); if (Settings.contains("left")) num = Settings.getInt("left", 0); text = findViewById(R.id.number); button = findViewById(R.id.button); button.setOnTouchListener(on); if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",  "); } } @Override protected void onPause() { super.onPause(); SharedPreferences.Editor editor = Settings.edit(); editor.putInt("left", num); editor.apply(); } } 


Código de resultado activity_main.xml
 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF"> <TextView android:id="@+id/number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="Hello World!" android:textSize="20dp" /> <ImageButton android:id="@+id/button" android:layout_width="90dp" android:layout_height="90dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="32dp" android:background="#000000FF" android:scaleType="fitXY" android:src="@drawable/b" android:visibility="visible" /> </RelativeLayout> 


Esto termina una disminución razonable en el archivo APK, luego hay una instrucción para reducir aún más la aplicación en detrimento de la facilidad de desarrollo.

Eliminar recursos


Elimine la carpeta res / values, en el archivo AndroidManifest.xml reemplazamos el bloque de la aplicación con el siguiente código:

 <application android:icon="@drawable/i" android:roundIcon="@drawable/i" android:label="Clicker" android:theme="@style/android:Theme.DeviceDefault.NoActionBar"> <activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /></intent-filter> </activity> </application> 

También reemplazamos los identificadores con los de una letra, cambie el nombre del archivo activity_main.xml a m.xml

Cambiar el procesamiento de clics:

Eliminar la linea

 button.setOnTouchListener(on); 

en MainLayout.java.
Reemplazar función

 View.OnTouchListener on = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { num--; if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",   "); } } return false; } }; 

en
 public void o(View v) { num--; if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",   "); } } 

En el archivo m.xml (anteriormente activity_main) en la estructura ImageButton, agregue la línea

 android:onClick="o" 

El tamaño total fue de 10,2 KB , 147 veces más pequeño que el tamaño inicial. Creo que este es un buen resultado.



Código MainActivity.java
 import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; public class MainActivity extends Activity { SharedPreferences Settings; ImageButton button; TextView text; int num = 31; public void o(View v) { num--; if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",   "); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.m); Settings = getSharedPreferences("settings", Context.MODE_PRIVATE); if (Settings.contains("left")) num = Settings.getInt("left", 0); text = findViewById(R.id.n); button = findViewById(R.id.b); if(num > 0) { text.setText(Integer.toString(num)); } else { num = 31; text.setText(",  "); } } @Override protected void onPause() { super.onPause(); SharedPreferences.Editor editor = Settings.edit(); editor.putInt("left", num); editor.apply(); } } 


Código M.xml
 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF"> <TextView android:id="@+id/n" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textColor="#000000" android:textSize="20dp" /> <ImageButton android:id="@+id/b" android:layout_width="90dp" android:layout_height="90dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="32dp" android:background="#000000FF" android:scaleType="fitXY" android:src="@drawable/b" android:onClick="o" android:visibility="visible" /> </RelativeLayout> 

Source: https://habr.com/ru/post/es417845/


All Articles