This is some actual combat notes recorded in this year’s project volume optimization, the article mainly aimed at APK package content optimization. The optimization methods mainly include bytecode, resources, packaging and configuration.
preface
Mobile network from 2G->4G->5G, network speed step by step, network rates are also gradually cheaper. Remember when I was in high school, 5 yuan /30M flow, happy for a month. Now give me 300M flow, maybe I’ll finish it later
A few years ago, when I started my Android development career, the company was very sensitive about the size of the APP package. Today, it is no longer very sensitive about the size of the APP package
But for
- The size of an APP package is particularly sensitive in places like Africa and India where Internet resources are scarce
- Apps with large traffic, such as wechat and Douyin, pay more attention to package volume
Therefore, I would like to share my notes on slimming APP with you today. (The content does not include plug-in,Split APK and other dynamic delivery technologies, but Only the client’s own optimization.)
APK package structure introduction
The APK package structure mainly contains
- Assets directory: Used to store static files that need to be packed into APK. The difference between ASSETS directory and RES is that assets directory supports subdirectories of any depth. Users can deploy the folder schema according to their own requirements. R file generates the corresponding resource ID, assets will not automatically generate the corresponding ID(without the business logic or code logic, for this is difficult to optimize)
- Lib directory: Native library files that applications depend on, in the form of
- Res directory: Res is short for resource. This directory holds resource files
- Resources. arsc file: a compiled binary resource file
- Meta-inf directory: Stores application signature information, which can be used to verify the integrity and signature of APK
- Androidmanifest.xml: application file configuration information
- Classes. Dex:
Let’s talk about the specific implementation of optimization.
Delete constant R files from classes.dex *.R$ *
As we know, Android’s Res resource generates a reference to the R file, as follows
public final class R {
private R(a) {}public static final class id {
public static final int action_container = 2131165209;
public static final int action_divider = 2131165211;
public static final int action_image = 2131165212;
public static final int action_text = 2131165218;
public static final int actions = 2131165219;
public static final int async = 2131165226;
public static final int blocking = 2131165232;
public static final int chronometer = 2131165246;
public static final int forever = 2131165290;
public static final int icon = 2131165299;
public static final int icon_group = 2131165300;
public static final int info = 2131165305;
public static final int italic = 2131165309;
public static final int normal = 2131165373;
public static final int notification_background = 2131165374;
public static final int notification_main_column = 2131165375;
public static final int notification_main_column_container = 2131165376;
public static final int right_icon = 2131165405;
public static final int right_side = 2131165406;
public static final int tag_transition_group = 2131165453;
public static final int text = 2131165456;
public static final int text2 = 2131165457;
public static final int time = 2131165461;
public static final int title = 2131165462;
private id(a) {}}public static final class drawable {... }public static final class dimen {... }... }Copy the code
These are constants, so is there any way we can delete this file and just use the constants in the references? In fact, it does. According to the APK package compilation process, the Android Transform is used to replace all constants in the class during the compilation process. BuildConfig, Rlayout, R$string,AppConstans, etc
Currently, Didi open-source a booster that can be used directly, without building booster-transform-shrink
The effect
After componentization or dependence on the third party R files, there are more and more constant files, and the effect is significant. According to one of douyin’s friends, after their project is optimized for this project, the package volume is reduced by about 2M.
For use in our project, it is not obvious that the optimized volume is about 1M.
Matters needing attention
Since it is to delete constants, all areas where reflection is used should be kept. If Didi booster is used, you can refer to Issues
Res resources
Android Lint removes unwanted resources
When the project is iterated over and over again, some resources are gradually out of use and become redundant. In many cases, we are too lazy to delete them, or we are afraid of problems if we delete them. To shrinkResources, Android Studio has a built-in lint utility that can help us remove unwanted resources.
Method entry
In addition to Android Studio Analyze’s Android Lint (Inspect Code) for removing unwanted resources and package size optimizations, some automatic optimizations for our Code also have obvious effects (performance, security, bug prevention, etc.).
- Android > Lint > Correctness (may affect application Correctness)
- Android > Lint > Performance (may affect application Performance)
- Android > Lint > Security (may affect application Security)
Lint details: google.cn/studio/lint
Code Cleanup is also very powerful and can reduce the number of manual Code review irregularities.
The picture
For picture optimization, there are mainly several points
9 images.
Use.9 images instead of large images of repeatable areas. Use the.9 tools in Android Studio or the SDK to create.9 images
xh-dpi
In addition to the icon, most domestic applications only set a set of resources XH-DPI, so it is recommended to use a set of image resources
Android native WebP support
We know that Webp compression ratio is higher than PNG, JPG/JPEG compression ratio, using Webp can reduce some package size.
- Starting with Android 4.0 (SDK >= 14), the native ImageView supports Webp, but does not support transparent channels
- Android 4.2 start (SDK >= 18
If your project’s minSdk is above 4.2 >= 18, you can convert all images to WebP format by right clicking the image.
Image compression
Image compression is also a link as long as. Image compression tools are many, PNG, webP can be easily compressed, for the application of high quality and volume requirements, it is recommended to use lossy compression, the visual effect of the image is not much.
Booster compression tool is recommended for PNG compression and webP compression. Booster-task-compression for WebP compression varies according to minSdk versions
Resources. Ars optimization
/drawable/welcome. PNG (res/drawable/welcome. PNG) r/s/a. PNG. It is possible to obfuscate resources with Java like obfuscation rules so that the number of bytes consumed is reduced. One problem is that these resource ids have been compiled into 32-bit ints and put into resources.arsc. Then the confusion should be modified at the same time resources. Arsc. Zhang Shaowen tinker, the author of the former wechat technology big year, open source AndResGuard, can solve such a solution, and optimization is ok. Details on how to use AndResGuard
Build. Gradle configuration
Com. Android. Tools. Build: gradle is android packaging tools, in the packaging can be generated APK package, volume optimization, here are some of the common optimization strategy.
buildTypes {
release {
buildConfigField 'String'.'TINKER_APP_ID'.'"d499a164a6"'
debuggable false //debug false
shrinkResources true // Remove unwanted resources
zipAlignEnabled true // Enable compression
resConfigs "zh" // Indicates that only Chinese is used
resConfigs "xhdpi" // Indicates that only the resource files in the xhdpi directory are used
minifyEnabled true // Turn on obfuscation
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
ndk {
// Select the. So library to add for the CPU type.
abiFilters 'armeabi-v7a'}}}Copy the code
The above are some common configurations that need to be noted
- To start obfuscation, the keep rule in the main project must be considered thoroughly
- ResConfigs needs to be negotiated with product design after opening
- In NDK, most domestic applications only support ARMabI-V7A (support floating point type, higher accuracy), and my application only uses AremabI-V7A architecture, which is supported by almost all ARM phones.
At the end of the article
This is the end of APP slimming. The above schemes have been practiced in the project. If there are any mistakes in the text, please advise.
Recommended reading
A brief analysis of the principle of Flutter performance