preface
There is no need to say more about the importance of package size. Package size directly affects users' downloading, retention, and even some manufacturers' pre installed mandatory requirements must be less than a certain value. However, with the iterative development of the business, the application will become larger and larger, and the installation package will keep expanding. Therefore, the reduction of package size is a long-term and continuous governance process.
- Improve the download conversion rate. The smaller the installation package, the higher the conversion rate.
- Reduce the cost of channel promotion.
- Reduce installation time, file copy, Library decompression, ODEX compilation and signature verification. The larger the package size, the more time-consuming.
- Reduce runtime memory, etc.
environment
- Android Studio Arctic Fox | 2020.3.1 Patch 2
- AGP 7.0
- Project address: Wan Android_ jetpack
Before optimization
- 4.7MB and 4.2MB are the download size of google play, which will be compressed.
In addition to the Analyzer provided by AS, there are ApkChecker, classysark and other tools.
Composition of APK
APK construction process
This is the official packaging process of the new version. Although some steps are omitted, the general process is relatively clear.
Simplify again:
Resource files Java file > dex file > APK
Optimization ideas
APK is essentially a compressed file and a product after packaging. The stages that can be used as the entry point are before and during packaging.
- Before packaging, reduce the packaged files, such as useless resources and code;
- During packaging, the products in packaging are compressed, such as resource files and So files;
Key words: reduction, compression.
General operation
1.Lint detects useless resource files
Analyze > Run Inspection by Name > Unused resources
Test results:
OK, delete it.
Note: because lint is a local static scan, dynamically referenced resource files will not be recognized and will also appear in the detection list.
2.Lint test code
Analyze > Inspect code
Test results:
Because this project is written in kotlin, you can directly see the test results under the kotlin directory.
Note: because lint is a local static scan, reflected and dynamically referenced class es will not be recognized and will also appear in the detection list.
3. Picture compression
tinypng online compression is recommended.
4.TinyPngPlugin
Manual compression is not efficient after all. You can use TinyPngPlugin one click compression.
plugins search for TinyPng installation. (there is no need to restart the plugin after installing the new version of AS)
Compression results:
9 pictures, you can see the effect is still very impressive. If there are many pictures, the effect is more obvious.
After the above operation, the packet volume is reduced by 4%, which is just a 4.7MB APK.
5.WebP
Can these 9 pictures continue to be optimized? Yes, the volume of WebP format is smaller, and AS also provides one click conversion support.
With ic_avatar.png as an example:
ic_avatar.png optimized original size 113.09KBTingPng compressed 36.85kbwebp8 66KB
It can be seen that after switching to WebP, the original size is reduced by nearly 93%~
6. Turn on confusion
minifyEnabled true. R8 code reduction is enabled by default.
buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
Use R8 with caution because:
R8 ignores all ProGuard rules that attempt to modify the default optimization behavior, such as - optimizations and - optimizationpasses.
Confusion can be turned on without using R8.
android.enableR8=false android.enableR8.libraries=false
Confusion reference: Android confusion from entry to mastery
7. Resource reduction
shrinkResources true
If some resource files are not sure whether they are still in use or not, and dare not delete them, or whether the requirements will change, so keep them first, what should we do in this case? Shrink resources can be used to shrink resources.
buildTypes { debug { minifyEnabled false } release { shrinkResources true minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
It should be used together with minifyEnabled. The principle is also very simple. After the code is removed, the referenced resources will become useless resources and can be further reduced.
8.so file reduction
For example, if a three-party live broadcast or browser is integrated, many so files may be provided. At first, it may be a brain copy into the project, but not all of them can be used.
For example, so of Various cpu architectures:
app/build/intermediates/cmake/universal/release/obj/ ├── armeabi-v7a/ │ ├── libgameengine.so │ ├── libothercode.so │ └── libvideocodec.so ├── arm64-v8a/ │ ├── libgameengine.so │ ├── libothercode.so │ └── libvideocodec.so ├── x86/ │ ├── libgameengine.so │ ├── libothercode.so │ └── libvideocodec.so └── x86_64/ ├── libgameengine.so ├── libothercode.so └── libvideocodec.so
At present, the mobile phone CPUs on the market are all based on ARM architecture, so just keep one of arm (except customized ones), and either armeabi-v7a or armeabi can be deleted directly.
android { defaultConfig { ndk { abiFilters 'armeabi-v7a' } } }
If the development needs simulator debugging, add the x86 architecture, and remember to remove the formal package, or in local Use variables in properties to control it.
If this piece has not been optimized before and there are many so files, it may be reduced by more than 30%. It's terrible!
9. Remove unused spare resources
Many overseas applications will be internationalized, but they can't adapt to so many languages. In addition to their own apps, there are also some official and third-party languages that can be configured uniformly.
defaultConfig { resConfigs("en","zh","zh-rCN") }
The same is true for resource files
defaultConfig { resConfigs("xxhdpi","xxxhdpi") }
10. Summary
Make a summary of the above operations to see the current effect.
2MB, the package volume is reduced by 57%, so terrible!
If it is a large project, the income is very considerable.
author: yechaoa
Advanced operation
The above is just some general operations. Let's look at some advanced operations.
1.resources.arsc resource confusion
Resource obfuscation is to shorten the originally lengthy resource path, such as changing res/drawable/wechat to r/d/a. Open source tool AndResGuard.
2. Remove useless third-party libraries
Not used after the introduction, or not removed after the function is removed from the shelf.
3. Tripartite library integration with repeated functions
For example, glass and picasso are both picture libraries. Just keep one of them.
4.ReDex
dex file is a product of packaging, and REDEX is an open source subcontracting optimization scheme of facebook. Refer to: REDEX.
5.so dynamic loading
The so files have been reduced previously, but the proportion of so files may still be large. We can consider dynamic distribution of so files except for the first startup. That is, the idea of plug-in, loading on demand, but with great benefits, there are also great risks. There are many case s to consider, such as download timing, network environment, thread process, whether there is a degradation strategy for loading failure, etc.
You can refer to facebook's open source SoLoader.
6. Plug in
Load on demand. The greater the income, the greater the risk. The risk is the same as above.
Extreme operation
If I want to be the best, what else can I do? ok, continue.
1. Switch to H5 or applet programs
Some functions may be too heavy to be native. For example, various promotional activities need to load various large pictures. Native functions are heavy and not dynamic enough. H5 is a good alternative at this time. However, if you do not support H5 or applet originally, accessing this capability may increase the packet volume and make a comparison.
2. Hacking function
Some functions may think very well, but the revenue is not large after going online. Whether it is necessary to rethink the value points, it is best to find data support and fight with the products.
3. Modify the source code of the third-party library and eliminate unnecessary code
For example, a fully functional third-party library utils is introduced, but it actually takes only a few. Extracting the source code can also reduce the package volume and reduce the compilation time of network download.
The disadvantage is that the upgrade cost is large.
4. Picture networking
That is, upload the picture to the server and reduce the package volume through dynamic download. The disadvantage is that the first loading depends on the network environment and needs to balance the loading speed and traffic. Images can be preloaded, but traffic consumption cannot be avoided. If you care about traffic indicators, you need to weigh them.
5.DebugItem
DebugItem mainly contains two kinds of information:
- Debug information. Parameter variables and all local variables of the function.
- Troubleshooting information. The correspondence between all instruction set line numbers and source file line numbers.
Remove the debug information and line number information. If it is not extreme, it is not recommended. You can refer to Alipay's Alipay App building optimization analysis: Android packet size is the most extreme compression.
6.R Field inline
Inline R Field can solve the problem of MultiDex 65536 caused by too many R fields, and this step can have an obvious effect on code slimming.
Meituan code snippet:
ctBehaviors.each { CtBehavior ctBehavior -> if (!ctBehavior.isEmpty()) { try { ctBehavior.instrument(new ExprEditor() { @Override public void edit(FieldAccess f) { try { def fieldClassName = JavassistUtils.getClassNameFromCtClass(f.getCtClass()) if (shouldInlineRField(className, fieldClassName) && f.isReader()) { def temp = fieldClassName.substring(fieldClassName.indexOf(ANDROID_RESOURCE_R_FLAG) + ANDROID_RESOURCE_R_FLAG.length()) def fieldName = f.fieldName def key = "${temp}.${fieldName}" if (resourceSymbols.containsKey(key)) { Object obj = resourceSymbols.get(key) try { if (obj instanceof Integer) { int value = ((Integer) obj).intValue() f.replace("\$_=${value};") } else if (obj instanceof Integer[]) { def obj2 = ((Integer[]) obj) StringBuilder stringBuilder = new StringBuilder() for (int index = 0; index < obj2.length; ++index) { stringBuilder.append(obj2[index].intValue()) if (index != obj2.length - 1) { stringBuilder.append(",") } } f.replace("\$_ = new int[]{${stringBuilder.toString()}};") } else { throw new GradleException("Unknown ResourceSymbols Type!") } } catch (NotFoundException e) { throw new GradleException(e.message) } catch (CannotCompileException e) { throw new GradleException(e.message) } } else { throw new GradleException("******** InlineRFieldTask unprocessed ${className}, ${fieldClassName}, ${f.fieldName}, ${key}") } } } catch (NotFoundException e) { } } }) } catch (CannotCompileException e) { } } }
At the same time, you can refer to the byte open source shrink-r-plugin and didi open source booster.
7. Picture shader
For the processing of different colors in the same image, you can use tint. For example, when a black return icon is used, now another page needs to use white, so you don't need two images, but use tint to modify it to white.
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_back_black" android:tint="@android:color/white" />
8. Reduce the use of ENUM
Each reduction of ENUM can reduce the size by about 1.0 to 1.4 KB.
Package volume monitoring
Package volume monitoring should be a part of the release process. It is best to achieve platform and process, otherwise it is difficult to continue, and the package volume of few versions has risen again.
General idea: compare the package size of the current version with that of the previous version. If it exceeds 200KB, it needs to be approved. Subsequent optimization schemes need to be given for temporary approval.
last
Some time ago, I collected and sorted out the knowledge brain map of Android performance optimization system and the notes of core knowledge points! It can not only consolidate the core technical points such as underlying principles and performance tuning, but also master the architecture design methodology that ordinary developers can't touch. Then you have the core competitiveness that your peers can't copy in your work, team and interview. The full version has been sorted and uploaded to Public account: Android development home , you can visit it yourself.
The full version of Android performance optimization system knowledge brain map and core knowledge points note document has been sorted and uploaded to Public account: Android development home , you can visit it yourself.