Diminuer la taille de l'APK (dans des limites raisonnables)

Il y avait déjà un article similaire sur Habr.com prouvant que vous pouvez réduire un fichier APK de 1,5 Mo à 1757 octets ou moins. Le but de cet article est de réduire la taille de l'application à une limite raisonnable, en préservant sa fonctionnalité et en mettant en évidence certaines subtilités et moments implicites.

Commencer


Créez un projet dans Android Studio, sélectionnez Activité vide. Ensuite, dans le fichier styles.xml, remplacez Activity par ActionBar

Theme.AppCompat.Light.DarkActionBar 

sur l'activité sans ActionBar

 Theme.AppCompat.Light.NoActionBar 

Le résultat:

image

Dans l'analyseur APK, nous voyons ce qui suit:



Ainsi, l'APK pèse 1,5 Mo, malgré le fait qu'il n'affiche que les mots "Hello World!".

Première étape (minification)


Dans le fichier build.gradle, nous écrivons:

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

Nous synchroniserons Android Studio pour que les modifications prennent effet.

Explication:

 minifyEnabled true 
supprimer le code inutile dans l'application
 shrinkResources true 
supprimer les ressources inutilisées de l'APK.

Le poids de l'APK est devenu 960 Ko, aucun changement dans les performances.

Étape deux (ajouter des fonctionnalités)


Pour que l'application ait un sens, ajoutez-y des fonctionnalités, par exemple un clicker.

Code 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> 


Code 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(); } } 

L'application a acquis le formulaire suivant:



Taille de l'application 1,1 Mo, soit une augmentation de 140 Ko.

Étape trois (supprimer android.support et AppCompat)


Actuellement, l'analyseur APK montre ce qui suit:



public class MainActivity extends AppCompatActivity par la public class MainActivity extends Activity dans MainActivity.java. Appuyez sur Alt + Entrée pour qu'Android Studio importe les bibliothèques.

La taille de l'application n'a pas changé, mais ...



Où est le bouton?

En fait, tout est en ordre, elle est restée cliquable. Mais elle n'a tout simplement pas de photo.

Accédez à activity_main.xml, trouvez la ligne ci-dessous

 app:srcCompat="@mipmap/ic_launcher_round" 

et changez-le en

 android:src="@mipmap/ic_launcher_round" 

Maintenant tout va bien:



Mais la taille n'a pas changé.

Nous revenons à build.gradle et effaçons le bloc de dépendance:

 dependencies { } 

Et synchronisez Android Studio ... avec des erreurs.

1. Accédez au fichier res / values ​​/ styles.xml et remplacez tout son contenu par le code suivant:

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

2. ConstraintLayout, qui est utilisé dans Android Studio, dépend de android.support, qui a déjà été supprimé du bloc de dependencies , nous allons donc remplacer ConstraintLayout par RelativeLayout, qui ne dépend pas d'android.support.

Code 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> 


Nous compilons l'APK et voyons le résultat:



Notre APK pèse 202 Ko, ce qui est 7,5 fois plus petit que sa taille d'origine.

La plupart des ressources sont occupées et nous nous en occuperons.

1. Supprimez les fichiers du dossier res / drawable et effacez le dossier res / mipmap
2. Dessinez votre icône et votre bouton, puis réduisez sa taille à l'aide d'ImageOptim.

Bouton:



Icône:



3. Téléchargez-les dans Android Studio, pour cela, sélectionnez-les dans le dossier, appuyez sur Ctrl + C, allez dans Android Studio, sélectionnez le dossier res / drawable et appuyez sur Ctrl + V, après quoi Andoid Studio offrira plusieurs options où transférer les images en fonction de leur permission.

Dans le dossier dessinable, vous pouvez renommer le fichier en sélectionnant Refactor -> Rename.
L'icône de l'application porte le nom i.png, l'image du bouton b.png

4. Accédez maintenant au fichier AndroidManifest.xml, lignes

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

remplacer par

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

Dans le fichier activity_main.xml, remplacez le champ dans ImageButton

 android:src="@mipmap/ic_launcher_round" 

sur

 android:src="@drawable/b" 

Résumé


La taille totale du fichier est de 13,4 Ko, soit 112 fois moins que la taille initiale!

Code 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(); } } 


Code de résultat 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> 


Cela met fin à une diminution raisonnable du fichier APK, puis il y a une instruction pour réduire davantage l'application au détriment de la facilité de développement.

Supprimer des ressources


Supprimez le dossier res / values, dans le fichier AndroidManifest.xml, nous remplaçons le bloc d'application par le code suivant:

 <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> 

Nous remplaçons également les identifiants par des identificateurs à une seule lettre, renommons le fichier activity_main.xml en m.xml

Modifiez le traitement des clics:

Supprimer la ligne

 button.setOnTouchListener(on); 

dans MainLayout.java.
Remplacer la fonction

 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; } }; 

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

Dans le fichier m.xml (anciennement activity_main) de la structure ImageButton, ajoutez la ligne

 android:onClick="o" 

La taille totale était de 10,2 Ko , 147 fois plus petite que la taille initiale. Je pense que c'est un bon résultat.



Code 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(); } } 


Code 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/fr417845/


All Articles