减少APK大小(在合理范围内)

Habr.com上已有类似文章证明,您可以将APK文件从1.5 MB压缩到1757字节或更小。 本文的目的是将应用程序的大小减小到合理的限度,并保留其功能并强调一些微妙和隐含的时刻。

开始


在Android Studio中创建一个项目,然后选择清空活动。 然后,在styles.xml文件中,将Activity替换为ActionBar

Theme.AppCompat.Light.DarkActionBar 

没有ActionBar的活动

 Theme.AppCompat.Light.NoActionBar 

结果:

图片

在APK分析器中,我们看到以下内容:



因此,尽管APK仅显示单词“ Hello World!”,但其重量为1.5 MB。

第一阶段(缩小)


在build.gradle文件中,我们编写:

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

我们将同步Android Studio,以使更改生效。

说明:

 minifyEnabled true 
删除应用程序中不必要的代码
 shrinkResources true 
从APK中删除未使用的资源。

APK的重量变为960 KB,性能没有变化。

第二阶段(添加功能)


为了使应用有意义,请向其中添加功能,例如,单击器。

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> 


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

该应用程序已获得以下表格:



应用程序大小1.1 MB,增加了140 KB。

第三阶段(删除android.support和AppCompat)


目前,APK分析器显示以下内容:



public class MainActivity extends AppCompatActivity public class MainActivity extends Activity 。 按Alt + Enter使Android Studio导入库。

应用程序的大小没有改变,但是...



按钮在哪里?

实际上,一切都井井有条,她仍然可以点击。 但她只是没有照片。

转到activity_main.xml,找到下面的行

 app:srcCompat="@mipmap/ic_launcher_round" 

并将其更改为

 android:src="@mipmap/ic_launcher_round" 

现在一切都很好:



但是大小没有改变。

我们再次去build.gradle并清除依赖项块:

 dependencies { } 

并同步Android Studio ...错误。

1.转到res / values / styles.xml文件,并将其所有内容替换为以下代码:

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

2.在Android Studio中使用的ConstraintLayout依赖于android.support(已从dependencies块中删除),因此我们将ConstraintLayout替换为不依赖android.support的RelativeLayout。

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> 


我们编译APK并查看结果:



我们的APK的大小为202 KB,比原始大小小7.5倍。

大多数资源都已占用,我们将处理它们。

1.删除res / drawable文件夹中的文件,并清除res / mipmap文件夹
2.绘制图标和按钮,然后使用ImageOptim减小其大小。

按键:



图标:



3.在Android Studio中下载它们,为此在文件夹中选择它们,按Ctrl + C,转到Android Studio,选择res / drawable文件夹,然后按Ctrl + V,之后,Andoid Studio将提供几个选项,用于根据需要传输图像在他们的允许下。

在可绘制文件夹中,可以通过选择“重构”->“重命名”来重命名文件。
应用程序图标的名称为i.png,b.png按钮的图片

4.现在转到AndroidManifest.xml文件,行

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

替换为

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

在activity_main.xml文件中,替换ImageButton中的字段

 android:src="@mipmap/ic_launcher_round" 



 android:src="@drawable/b" 

总结


文件总大小为13.4 KB,比初始大小小112倍!

最终代码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(); } } 


结果代码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> 


这样就可以合理地减少APK文件的数量,然后有一条指令可以进一步减少应用程序,从而不利于易于开发。

删除资源


删除res / values文件夹,在AndroidManifest.xml文件中,我们将应用程序块替换为以下代码:

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

我们还将标识符替换为单字母标识符,将activity_main.xml文件重命名为m.xml。

更改点击处理:

删除行

 button.setOnTouchListener(on); 

在MainLayout.java中。
替换功能

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


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

在ImageButton结构的m.xml文件(以前为activity_main)中,添加以下行

 android:onClick="o" 

总大小为10.2 KB ,比初始大小小147倍。 我认为这是一个很好的结果。



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


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/zh-CN417845/


All Articles