Diminuir o tamanho do APK (dentro de limites razoáveis)

Já havia um artigo semelhante no Habr.com provando que você pode reduzir um arquivo APK de 1,5 MB para 1757 bytes ou menos. O objetivo deste artigo é reduzir o tamanho do aplicativo a um limite razoável, preservando sua funcionalidade e realçando algumas das sutilezas e momentos implícitos.

Iniciar


Crie um projeto no Android Studio, selecione Atividade vazia. Em seguida, no arquivo styles.xml, substitua Activity por ActionBar

Theme.AppCompat.Light.DarkActionBar 

em Atividade sem ActionBar

 Theme.AppCompat.Light.NoActionBar 

O resultado:

imagem

No analisador APK, vemos o seguinte:



Portanto, o APK pesa 1,5 MB, apesar de exibir apenas as palavras "Olá, mundo!".

Estágio Um (minificação)


No arquivo build.gradle, escrevemos:

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

Sincronizaremos o Android Studio para que as alterações entrem em vigor.

Explicação:

 minifyEnabled true 
remova código desnecessário no aplicativo
 shrinkResources true 
remova recursos não utilizados do APK.

O peso do APK se tornou 960 KB, sem alterações no desempenho.

Estágio dois (adicionar funcionalidade)


Para que o aplicativo faça sentido, adicione funcionalidade a ele, por exemplo, um 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(); } } 

O aplicativo adquiriu o seguinte formulário:



Tamanho do aplicativo 1,1 MB, um aumento de 140 KB.

Estágio três (remova android.support e AppCompat)


Atualmente, o analisador APK mostra o seguinte:



public class MainActivity extends AppCompatActivity pela public class MainActivity extends Activity em MainActivity.java. Pressione Alt + Enter para que o Android Studio importe as bibliotecas.

O tamanho do aplicativo não mudou, mas ...



Onde está o botão?

Na verdade, está tudo em ordem, ela permaneceu clicável. Mas ela simplesmente não tem uma foto.

Vá para activity_main.xml, encontre a linha abaixo

 app:srcCompat="@mipmap/ic_launcher_round" 

e mude para

 android:src="@mipmap/ic_launcher_round" 

Agora está tudo bem:



Mas o tamanho não mudou.

Vamos novamente para build.gradle e limpar o bloco de dependência:

 dependencies { } 

E sincronize o Android Studio ... com erros.

1. Vá para o arquivo res / values ​​/ styles.xml e substitua todo o seu conteúdo pelo seguinte código:

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

2. O ConstraintLayout, usado no Android Studio, depende do android.support, que já foi removido do bloco de dependencies , portanto, substituiremos o ConstraintLayout por RelativeLayout, que não depende do 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 o APK e vemos o resultado:



Nosso APK pesa 202 KB, 7,5 vezes menor que o tamanho original.

A maioria dos recursos está ocupada e vamos lidar com eles.

1. Exclua os arquivos na pasta res / drawable e limpe a pasta res / mipmap
2. Desenhe seu ícone e botão e reduza seu tamanho usando o ImageOptim.

Botão:



Ícone:



3. Faça o download deles no Android Studio. Para isso, selecione-os na pasta, pressione Ctrl + C, vá para Android Studio, selecione a pasta res / drawable e pressione Ctrl + V, após o qual o Andoid Studio oferecerá várias opções para transferir as imagens, dependendo da permissão deles.

Na pasta drawable, você pode renomear o arquivo selecionando Refatorar -> Renomear.
O ícone do aplicativo tem o nome i.png, a imagem do botão b.png

4. Agora vá para o arquivo AndroidManifest.xml, linhas

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

substituir por

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

No arquivo activity_main.xml, substitua o campo no ImageButton

 android:src="@mipmap/ic_launcher_round" 

em

 android:src="@drawable/b" 

Sumário


O tamanho total do arquivo é 13,4 KB, 112 vezes menor que o tamanho 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> 


Isso encerra uma diminuição razoável no arquivo APK, então há uma instrução para reduzir ainda mais o aplicativo em detrimento da facilidade de desenvolvimento.

Excluir recursos


Exclua a pasta res / values, no arquivo AndroidManifest.xml, substituímos o bloco do aplicativo pelo seguinte 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> 

Também substituímos os identificadores pelos de uma letra e renomeie o arquivo activity_main.xml para m.xml

Altere o processamento de cliques:

Excluir a linha

 button.setOnTouchListener(on); 

em MainLayout.java.
Substituir função

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

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

No arquivo m.xml (anteriormente activity_main) na estrutura ImageButton, adicione a linha

 android:onClick="o" 

O tamanho total era 10,2 KB , 147 vezes menor que o tamanho inicial. Eu acho que esse é um bom 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/pt417845/


All Articles