Today’s share is slimming experience from mobile client of brother department. Welcome to pay attention to iQiyi technology product team public number, more from iQiyi technology sharing and summary.
The author | Jully
The authors introduce
Jully, graduated from Harbin Institute of Technology in 2010, joined IQiyi in 2013, and is now a senior program girl in the technical Product Center. Engaged in iQiyi Android mobile client development, mainly responsible for client push, Android new feature research and APK slim, etc.
Please enter the title abcdefg
Read the guide
APK slimming value
Users often avoid downloading apps that are too large, especially when using mobile traffic. In addition, apps that are too large will occupy more memory and consume more resources, resulting in slower installation and loading speed, especially on low-equipped phones.
As a leading mobile APP on the Internet in China, IQiyi attaches great importance to the user experience of APP clients, always pays attention to the volume of APK, and continues to follow up and optimize.
At present, IQiyi Android APK size index in the video industry and even the entire mobile Internet has been in a leading position, the following is our APK slimming road to share some experience.
I. APK composition structure
Using some pretty cool methods
To reduce the size of your application,
You must first understand the actual APK file format.
In short,
APK is a compressed file containing files/folders.
As a developer,
We can pass easily
Open the compressed file to view the contents of APK.
1. 7zip Open the APK view
2. Function of each file or folder
Files/folders
Function/function
res
Contains all resource files that are not compiled into the. Arsc
lib
The folder that references the library
assets
Compared to the RES folder, the Assets folder may also contain font files, preset data, and Web pages, which can be accessed through AssetManager
META_INF
Signature information is stored to ensure the integrity of APK packages and system security. When an APK is generated, a validation calculation is performed on all the packaged files and the results are placed in this directory
classes.dex
Contains dex bytecode converted from compiled application source code. There may be multiple dex files in APK
resources.arsc
Some resources and identifiers are compiled and written to this file
Androidmanifest.xml
At compile time, the application’s Androidmanifest.xml is converted to binary format
3. Proportion of APK components of IQiyi
Through iQiyi Android client
As you can see from the pie chart of APK,
Libs, RES and DEX account for a large proportion in APK.
APK slimming scheme
Through the above analysis,
You have understood the basic structure of APK.
Here we use a variety of methods for APK weight loss
2.1 For overall optimization
2.1.1 pluggable
From the perspective of application function expansion, the increase of APK package size is inevitable, but the emergence of plug-in technology is a good solution to this problem.
Comparatively independent module through the separation of application, and then in the form of plug-ins to load, such as iQIYI Android client has many relatively independent functions, games, cartoons, literature, movie tickets, app store, etc., are all through the way of plug-in, download from the server, and then loaded into our main project in the form of a plug-in.
As for plug-in, related technologies will be shared in the future. There is no more description here. If you are interested, please pay attention to our public account.
2.1 For overall optimization
2.1.2 7 zip compression
In general, in APK generated by direct compilation of AS, the.arsc file is not compressed at all, AS can be seen from the first figure of the APK component in the previous article.
Next, we decompress APK and re-compress it with 7zip. We will find that almost all files are smaller, especially.arSC files, which are much smaller.
Comparing the changes of files in APK before and after 7zip compression, it can be seen that by 7zip compression,.arsc files are about 2M smaller, and other files/folders are about 5% smaller.
2.1 For overall optimization
2.1.3 Signature Mode
Google’s new apksigner signature tool is available for Android7.0, which reduces the size of APK by about 5% (depending on the number of files) compared to the jarsigner signature tool provided by Java.
Let’s see
Two different signature modes
The change in APK volume
The first APK is unsigned, the second is signed using Jarsigner, and the third is generated using the Apksigner signature.
It can be seen that the APK generated with apksigner signature is 1.1M smaller than that generated with Jarsigner signature.
So let’s see
These two APK signatures
What are the file size differences
In the middle of the image is the unsigned APK,
On the left, signed by Jarsigner,
On the right is signed by Apksigner.
Compared with the unsigned APK, all compressed files and folders in THE APK have increased in size with the Jarsigner signature tool. The apkSigner signature tool does not change the size of files and folders except for the META_INF folder.
The reasons for the above changes are:
Jarsigner signs each file, then calculates the summary for the signed file and writes it to the manifest.mf file in the meta-INF folder. Apksigner calculates a summary of all files directly and writes it to the manifest.mf file.
The new Apksigner tool has been integrated into the Android 7.0 SDK.
https://developer.android.com/studio/command-line/apksigner.html
2.1 For overall optimization
2.1.4 Comparison of APK before and after weight loss
In different versions by different means
Details of APK slimming,
As follows:
Plugins are optimizations that were made two years ago,
7ZIP compression and signature are recent optimizations,
And achieved by Jenkins automation script.
2.2 Optimization for resources
2.2.1 Removing Duplicate Resources
1. A set of resources
When Android ADAPTS image resources, if there is only one set of resources, low-density phones will zoom the image, and high-density phones will stretch the image. We use this feature to store a set of resource maps that can be used by phones of all densities.
Considering image definition, static size and memory usage, resource images under XHDPI are generally adopted.
2. Duplicate resources
Many times, as projects grow and developers change, some resource files have different names but identical content. We can scan the MD5 value of the file, find out the pictures with different names and the same content and delete them, so that the pictures do not repeat.
2.2 Optimization for resources
2.2.2 Removing Unnecessary Resources
Due to various factors such as project iterations and UI revisions,
It will lead to the existence of many useless resources in the project,
Periodically scan for unwanted resources.
1. Scan for project resources using Lint
When Lint scans for unwanted resources, it prints the following message to remove the resource.
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
to be unused [UnusedResources]
In particular, ensure that there is no reflection or resource splicing to access these resources, so that these resources can be safely deleted and the number of resources can be reduced.
2. Configure Gradle parameters
If the project is large and consists of a main project and several sub-projects, the sub-projects may also contain a lot of useless resources. By setting shrinkResources=true, Gradle can remove unwanted resources. Otherwise, by default, Gradle builds to remove unwanted code and does not care about unwanted resources.
android {
// Other settings
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles
getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’
}
}
}
Note that shrinkResources depends on minifyEnabled and must be used with minifyEnabled.
3. Use the open source scanning tool
You may find that Lint is not very easy to use when there is reflection in the project and the filtering results are cumbersome.
So we implemented a resource scanning tool
(https://github.com/zhuzhumouse/ScanUnusedResouce),
Resources called through reflection can be filtered out.
The principle is to scan all Java and XML files into the memory as strings, and then get the names of resource files (XML, PNG, JPG, etc.) for matching search. If no match is found, the resource is useless and can be deleted directly.
The scanning tool can solve the problem of reflection calls, but it can’t solve the problem of resource concatenation, and it can’t handle the situation where there are many resources with the same prefix.
2.2 Optimization for resources
2.2.3 PNG image compression
PNG images can be compressed by using image compression tools. The best compression tools are:
Pngcrush, pngquant zopflipng etc.,
You can reduce the size of the image while maintaining the quality of the image.
You can also compress pictures through websites, such as the more famous www.tinypng.com, which automatically selects the appropriate compression algorithm for uploaded pictures, with a high compression ratio, but only 500 free pictures are supported, and more picture processing is charged.
2.2 Optimization for resources
2.2.4 WebP format is adopted
WebP is divided into lossy compression, lossless compression and lossy compression including transparency.
Lossy WebP is based on the predictive coding method in VP8 video coding to compress image data. Lossless WebP uses different technologies to transform image data; Lossy WebP(transparency support) is distinguished from lossy WebP and lossless WebP. This encoding allows lossless encoding of RGB channels while lossless encoding of transparent channels.
Currently, mobile systems 4.2 and above support lossless and lossy compression of WebP, but mobile systems 4.0 and 4.1 only support lossy compression without transparency. If the lowest version (minSdkVersion) supported by the application is 4.0, then WebP conversion can only be done for images without transparency.
On Android Studio 2.3 and above, you can select the Drawable and Mipmap folders, right-click and select Convert to WebP to convert the image to WebP format. If the Android Stuido version is relatively low, you can directly use the official cWebP tool to convert PNG to WebP.
Below are two detailed comparison pictures of PNG to WebP:
For example the sample figure
png (KB)
WebP 75 (KB)
WebP 90 (KB)
120
2.7
5.78
10
15
27
It can be seen from the conversion results of the above two sample images that not all images have high compression ratio, and some images will increase after compression, such as the second sample image. WebP is relatively small color difference of the picture, the compression ratio will be relatively high, any kind of compression algorithm can only have a certain characteristics of the picture compression, there is no universal compression method.
2.2 Optimization for resources
2.2.5 Optimize resources in the library
Often in large projects, many system libraries and third-party libraries are introduced.
For example, low version compatible library V4, V7, network request library, image processing library, etc., if the library contains some large pictures, and we will not use, you can use 1X1 transparent picture instead, to achieve both compilation through, and can reduce the volume of the library.
2.2 Optimization for resources
2.2.6 Large background image processing
For large pictures with high definition requirements, the simple compression method cannot meet the requirements of UE, and a non-compression method needs to be found to solve this problem.
Solid color map + background download is a good way to solve this problem, the client first use solid color picture, and then the large download from the back end, so that only the first few times to use the solid color map, the future will use the large picture.
2.2 Optimization for resources
2.2.7 Use of Lottie Animation library
Animation, especially frame animation, has always been quite resource-intensive. Airbnb’s open source Lottie animation library can now be used to describe animations directly in JSON files, and then directly loaded and drawn.
Specific use reference:
https://github.com/airbnb/lottie-android
2.2 Optimization for resources
2.2.8 Other Resource Policies
1. First consider whether you can use shape code to implement without images.
Secondly, if pictures are used, can they be used preferentially? 9.
3. Use SVG vector diagrams and VectorDrawable classes to replace traditional images.
4. If the image is only rotated or the color is different, you can use code to achieve transformation.
2.2 Optimization for resources
2.2.9 Comparison of APK before and after resource slimming
Details of the resource optimization scheme used by iQiyi client
As is shown in
At present, iQiyi client uses these four resource optimization methods.
The original xhdPI and xxhdpi clients have overlapping resources. After deleting the resources, the package size is reduced by 1 MB. To remove unnecessary resources, you can obtain the list of unnecessary resources through your own scanning tool and confirm processing. Pngquart compression is implemented through Gradle automation scripts during the packaging process; WebP format is a Python script that iterates through images without transparency and replaces them with WebP transformations.
2.3 Optimization for code
The optimization method of resource files has been described in detail above.
Through these optimizations,
The package volume is significantly reduced,
Let’s talk about code optimization again.
2.3 Optimization for code
2.3.1 Code confusion
Use minifyEnabled in Gradle
To configure Proguard obfuscation,
Can greatly reduce the size of APP:
Here are the details of APK before and after the code obfuscation
In particular, attention should be paid to:
In the proguard,
Whether or not to keep the symbol table has a significant impact on the size of the APP,
May not be retained at their discretion,
However, it is recommended to reserve it for debugging as much as possible.
2.3 Optimization for code
2.3.2 Useless code scanning
As with the garbage scan method, it is possible to scan for garbage code, but it is important to note that some classes and methods of the main application that are called by reflected methods in the plug-in cannot be deleted.
SonarQube can also be used to scan for useless classes and duplicate code in different classes.
Please refer to:
https://github.com/SonarSource/sonarqube
2.3 Optimization for code
2.3.3 Deleting R files
As the resources in the project increase, you will find that the r.class file in the generated dex file becomes larger and larger. We know that where resources are really used, they are accessed as r.xx. XXX, and r.xx. xx corresponds to a constant value in the.arsc file. The contents of ARSC are as follows:
1) How string resources are stored in. Arsc files
2) Layout below the Xml resource file in the. Arsc file storage mode
From these two screenshots, we can see that replacing the resource access code r.xx.xxx with the ID makes the r.lass file useless and can be deleted, and the resource access string in the code becomes a constant, reducing the dex size in both ways.
Removing R files can refer to open source tools:
https://github.com/meili/ThinRPlugin
2.3 Optimization for code
2.3.4 Annotations instead of enumerations
Google officials have long strongly recommended using annotations instead of enumerations, both to reduce package size and to save memory. Let’s compare the content of the generated class file when using annotations versus enumerations.
Enumeration type source code
public enum MarkViewType3{ SIMPLE_TEXT_MARK, DO_LIKE_MARK, BOTTOM_BANNER1, BOTTOM_BANNER2, TL_GREY_BACKGROUND_RANK, /** * service navigation mark */ SERVICENAVIRIGHTMARK, /** * Search for page hot events, titles, comments, events */ BOTTOM_COMPOUND_TEXT_BANNER}
Class file generated after dex compilation
public enum MarkViewType3 { static { DO_LIKE_MARK = new MarkViewType3(” DO_LIKE_MARK“, 1); BOTTOM_BANNER1 = new MarkViewType3(” BOTTOM_BANNER1“, 2); BOTTOM_BANNER2 = new MarkViewType3(” BOTTOM_BANNER2“, 3); TL_GREY_BACKGROUND_RANK = new MarkViewType3(“TL_GREY_BACKGROUND_RANK“, 4); SERVICENAVIRIGHTMARK = new MarkViewType3(“SERVICENAVIRIGHTMARK“, 5); BOTTOM_COMPOUND_TEXT_BANNER = new MarkViewType3(“BOTTOM_COMPOUND_TEXT_BANNER“, 6); $VALUES = new MarkViewType3[] { SIMPLE_TEXT_MARK, DO_LIKE_MARK, BOTTOM_BANNER1, BOTTOM_BANNER2, TL_GREY_BACKGROUND_RANK, SERVICENAVIRIGHTMARK, BOTTOM_COMPOUND_TEXT_BANNER }; }}
By comparison, you can see that in the generated class file,
Each variable is an object,
And there’s an array of value objects.
Annotation implementation source code
public class MarkViewType1{ public static final int SIMPLE_TEXT_MARK = 0; public static final int DO_LIKE_MARK = 1; public static final int BOTTOM_BANNER1 = 2; public static final int BOTTOM_BANNER2 = 3; public static final int TL_GREY_BACKGROUND_RANK = 4; /** * Public static final int SERVICENAVIRIGHTMARK = 5; Public static final int BOTTOM_COMPOUND_TEXT_BANNER = 6; @IntDef ( {SIMPLE_TEXT_MARK, DO_LIKE_MARK, BOTTOM_BANNER1, BOTTOM_BANNER2, TL_GREY_BACKGROUND_RANK , SERVICENAVIRIGHTMARK, BOTTOM_COMPOUND_TEXT_BANNER}) @Retention(RetentionPolicy.SOURCE) public @ interface MarkViewType1Anno{ }}
Generated class file
public class MarkViewType1 { public static final int BOTTOM_BANNER1 = 2; public static final int BOTTOM_BANNER2 = 3; public static final int BOTTOM_COMPOUND_TEXT_BANNER = 6; public static final int DO_LIKE_MARK = 1; public static final int SERVICENAVIRIGHTMARK = 5; public static final int SIMPLE_TEXT_MARK = 0; public static final int TL_GREY_BACKGROUND_RANK = 4; @Retention(RetentionPolicy.SOURCE) public static @ interface MarkViewType1Anno { }}
The class files generated by annotations are just constants.
As you can see from the code comparison above, the constant + annotation form can reduce the number of bytes of the generated class file on the one hand and reduce the memory overhead on the other hand.
2.3 Optimization for code
2.3.5 Code before slimming sum
APK comparison after weight loss
Iqiyi client code optimization details
As is shown in
As you can see from the figure above, code obfuscation can significantly reduce package size, especially if more third-party libraries are introduced. So when packaging, you should turn on code obfuscation, as well as resource obfuscation.
Annotation instead of enumeration, after trying, found that after a lot of modification, it is not helpful to reduce the package size, so iQiyi client did not adopt this scheme.
2.4. Arsc file optimization
You have seen the.arSC file content format in the Section culling R files. In the overall optimization section,. Arsc has been greatly optimized, and other optimization methods will be analyzed next.
Arsc files can be optimized by obfuscation to reduce the names of resource files and by removing unused standby resources. How do I remove an unused standby resource from Gradle
Added the following configuration:
android {
defaultConfig {
.
resConfigs “zh“, “zh_CN“, “zh_HK“, “zh_MO“, “zh_TW“, “en”
}
}
In this way, the size of the iQiyi client package can be reduced by more than 100 KB.
2.5 Lib Directory Optimization
Only support for mainstream architecture, such as ARM, MIPS and x86 architecture can be considered not to support, the system will automatically provide corresponding compatibility. The iQiyi client only places a set of so library files under Armeabi.
In addition to plugins, the client also uses RN’s scheme, thus introducing RN’s so library. Since RN’s SO library resources are relatively large, more than 2M, the plug-in of RN’s SO library is introduced. Through the plug-in of so library, to reduce the package size. RN library plug-in, package size reduced by more than 1M.
2.6 Package slimming details summary
Use all of the above to slim down,
Details of APK changes,
As shown below:
As can be seen from the figure above, after code optimization, resource optimization, lib library optimization,.arsc file optimization, and overall optimization, the package size was reduced from 54.2m to 28.2m.
Three. Problems encountered in the slimming process
1. WebP support problems
In the process of converting WebP pictures, we must pay attention to the situation of resource stitching.
For example, if there are five resources vip_1, VIp_2, VIp_3, VIp_4,vip_5, they can either be converted to WebP, or none of them can be processed.
When replacing some bootstrap diagrams, be sure to replace both the packaging tool and the client. If the client replaces the boot image with WebP format and the image is replaced with PNG format due to unsynchronization during packaging, the resource will fail to load and the application will crash.
2. Signature mode
Before using apkSigner, you must run zipalign. With the Jarsigner signature tool, you sign first and then optimize with Zipalign.
4. Summary
At present, iQiyi Android client mainly through plug-in, RN, signature, 7ZIP compression, retain a set of resources, code resource confusion, useless resource processing, R file elimination, image compression and other ways to reduce the package size, the overall package size reduced by more than 20M.
Shrinking package volume is a long-term task, there is still much to be done, such as regular scanning useless code and resources, image continuously optimize resources, extensive use of the vector diagram, Lottie animation, etc., with the emergence of new technology, we will have more ways to reduce the size of our package, makes the application more lightsome faster.
*
The resources
1. Reduce APK Size
2, Shrink Your Code and Resources
3. Create WebP Images
4, WebP file compression
PNG file format
6. How did Facebook engineers improve their Android client
7. Remove R files
8, picture compression artifact Tinypng
9, PngQuat image compression
If you feel good, please share it with your friends!