How do I think about this

APK is the file format of the Android system installation package. In fact, this topic is a platitude. No matter in the company or the external network, many methods and rules have been summarized by predecessors and predecessors. However, with the rapid development of mobile terminal technology in the past two years, some new ways of thinking and optimization methods have gradually emerged and matured. The author stepped on some pits in the practice process, harvested some experience, here to do a reflection and summary, so the essay to everyone, I hope to be helpful and reference to everyone engaged in the relevant work, but also to throw a brick to attract jade, I hope we discuss this open topic together.

As for why APK is slimming down, I won’t go into details here, but I’ll just talk about three things. For users (or customers), the bigger APK is, the more data they consume and the longer the wait for installation. For the product itself, this means a lower download conversion rate (because users have more chances to choose the one with the best experience, most features, best performance and smallest package); For r&d, it is an opportunity to optimize and improve the technology.

To slim down, we first look for fat causes and problems. According to the goal-path-resource thinking mode, there are several ways to find reasons and problems. One is to pat your head, according to your own experience and judgment, or even subjective imagination. Second, go to search engines to find keywords, visit all kinds of technical forum to listen to what the technology masters say, see all kinds of technical articles extraction refining; The third is to use a measurable tool or method to find problems.

I don’t need to talk about the first two, but I want to talk about the third method. Use a measurable tool or method to analyze, the so-called work to do a good job, must first sharpen its tools. This tool can be forged or made off the shelf. Here is a recommended online APK analysis tool, because it is an external tool, so please do not upload unreleased products in the process of use. For data security, the author here takes an open source Android project on Github as a slim example.

Looking for problems

NimbleDroid is an Android app performance analysis system developed by the Ph.D. team at Columbia University. The analysis methods are static and dynamic. The static analysis can analyze the ranking of large files in APK installation packages, the size of various well-known SDKS, and the percentage of the total code. The size and ranking of various types of files, the number of methods of various well-known SDK and the proportion of the number of methods in all dex, no more talking, below the high definition without code big picture to see the appearance level.

If you want to use the analytics function to analyze your product, please log in and upload the APK package of your product. All functions are currently free to use. If you want to analyze the products that have been released on Google Play, you can directly click on “Play Apps” to view the results. Again, please do not upload any unreleased products.

sThe login



sUpload apK files



sAnalysis results summary, you can see some overview information, APK file size, total method number



sFile size analysis detail page, list of large files, here lists the file rankings in APK files over 100K, file size here refers to the size of apK files



sThe size of the various well-known SDKS and their proportion to the overall code, Android Support is currently identified here, Jackson JSON Parser, Google Play Services, Paypal, Glide, OkHttp, Facebook SDK, Fabric, Gson and more, Application represents the part of the App that you write yourself



sSize and ranking of various types of files



sRatio of well-known SDKS to the number of methods in all Dex



sVarious well-known SDK methods list



Is it refreshing to see this APK profile? I compare this analysis tool to the smart scale we bought at home, which measures weight, fat content, bone mass, bone mineral density, muscle content, etc., so, are we seeing some problems, and then we can logically relate these problems to our previous experience and a pat on the head.

Then, we can sort out our optimization goals by analyzing the data

1. There are 11 PNG files that are over 100K in size, and remember, this is compressed

2. In the list of large files, the size of Resources.arsc is close to 2M, which is also an optimization point;

3. Classes. dex is close to 3M in the leaderboard of large files. Classes. dex is the carrier of code.

4. Android Support, Jackson JSON Parser and Google Play Services are the top three libraries in the component ratio ring chart.

5. PNG, DEX and ARSC are the top three in the list of file types;

Sorting out optimization objectives

So our goal is to have no cavities, no, the following goal:

1. pngImage optimization;

2. resources.arscFile optimization;

3. Code optimization

3.1 Image optimization attempts

Let’s start with the first goal, image optimization. Wait a minute, let’s see why these images are so big. First, let’s see why these images are so big in APK.

sThis time with some simple tool combination, the system comes with CMD is good.

■ The command execution result is as follows

All PNG files are stored in apK as STORE. For details about STORE and DEFLATE in ZIP, see DEFLATE.

Generally speaking, when a file is STORED in a ZIP, it means that the file is not compressed. If it is Defl:N, it means that the file is compressed into a ZIP in DEFLATED normal mode.

This seems a little unreasonable, PNG is put into ZIP as it is, but of course the apK will be bigger. So, how to solve it? I first tried using android Gradle Plugin and found aaptOptions and packagingOptions failed to solve the problem. Github found an open source project AndResGuard on Github and tried to integrate it into the project. The results are as follows:

sBefore optimization:



10536027byte

sAfter the optimization:



Normal ZIP compression: 8786265 bytes (nearly 17% compression)

7ZIP: 8567150 bytes (nearly 19% compression)

What does this tool do, before and after resource obfuscation

sBefore optimization



sThe optimized



1. Resource (PNG, XML, JPG, etc.) name confusion, resource path name confusion and name length compression;

2. PNG files STORED in zip are DEFLATED instead of STORED in ZIP.

Resources. Arsc, meta-inf /*.SF, and meta-INF /*.

sDecompile artifact with APKjadxLook inside APK for the truth



The relative paths of the original APK resources (PNG, XML, and properties files) are stored in meta-INF /*.sf and meta-INF /*.mf, and the SHA1 value is calculated for each resource file and stored in these two files. As for why this is done and what are the differences and functions of these two SHA1’s, please refer to the online articles about this knowledge. It is beyond the topic of this article, so I will not repeat it here.

sFor the resources.arsc file



It’s easy to see that it’s a resource file index, so you can see why these three files are getting smaller.

3.2 An unexpected discovery

sIf you look down at resources.arsc, you find something interesting,



This will be another optimization point, remove the useless translation resources and introduce some third-party SDKS, which usually come with a lot of translation resources, such as the Android Support library, after removing it, we will see the effect.

Suppose we just keep English, which is just an experiment, but it depends on the situation,

7ZIP compression: 8220738 bytes (nearly 22% compression, plus 3 points)

Of course, that would never happen in a real project, but mosquito meat is meat!

In fact, what I want to say is that this provides an optimization idea, which is to use gradle configuration to eliminate useless resources. The same can be used for the so local library. Gradle configuration has been deprecated.

sgradleThe configuration example is as follows:



Remember that the package is in the middle of android{}. So, one wonders, why is there no x86 in the ABI? It is said that Intel provides a solution called Houdini, which is a middleware running on x86 devices and can translate ARM into x86 instructions. However, the efficiency is very low. Some algorithms, such as MD5 and SHA1, are even worse than Java. Interested readers can move on.

At this point, we are on our way to the first goal, and we stumble upon the relationship between the first goal and the second goal, so we use the resource obfuscation tool to achieve the second goal.

Using 7ZIP compression, we compressed the entire package by 2 points, which was a better result than expected.

3.3 Image optimization methods

For the first goal, our path is not finished yet, the path that comes up is compressed PNG, non-alpha image into JPG, what else? So I went to a variety of technical forums to visit, consult a variety of technical masters, comb the path is as follows:

1. Manual lint checking, where resources that are not referenced in the code are manually removed, has varying effects.

Open “Analyze” in Android Studio and select “Inspect Code…” , scope select the entire project and click “OK”

sThe configuration is shown below.



2.gradleShrinkResources is enabled in the script

sThe script reference is as follows



ShrinkResources works best with minifyEnabled. See Usage and Precautions for shrinkResources

7zip compression: 8115,283 bytes (nearly 23% compression, plus 1 point)

3. Use the image compression tool to compress the size of PNG images and convert non-alpha images into JPG forms. Colleagues and Internet giants have sorted this out in great detail.

  • When using Tinypng, I just want to say that we are making products in the company, and this scheme should be used with caution. Uploading any content of unreleased products to the external network may cause data leakage, so use this scheme with caution. Here’s the alternative.

  • WASTED

  • pngquant

  • ImageAlpha

  • ImageOptim

  • The above tools are too scattered, there is no integrated tool, the answer is “yes”, @Xinlun children shoes developed imagemin

  • MSImageResourcesHelper developed by @brother-in-law Children’s Shoes

  • PNG to JPG format specific effect varies.

4. The ultimate killer, PNG into WebP, about WebP, for more details please refer to Google official documentation and Android developers online reference

sFirst, the effect picture:



Using 7ZIP compression: 4926912 bytes (nearly 53% compression, plus 30 points)

The current APK size is less than half the size of the original APK, and all I have done is one line of code unchanged, just using some tools!

Speaking of words, I did not take diet pills, did not fast, but lost half my weight!!

However, it is currently not used in the project because there are two pits

  • On some Models of Samsung, there will be an obvious black line in the graph with alpha background, which will not be shown here. This problem is dealt with by whitelisting rather than making webP graphs.

  • On the mobile phone whose Mi 2 was painted as 4.xx, the WEBP picture described in the XML file could not be correctly recognized. As a result, the XML layout file was loaded after the interface was up. The file failed to load webP, and the error message was “Resource file not found”, causing the app to crash. It was found that The MIUIResource class was represented as MIUIResource by Xiaomi machine, but the MIUIResource failed to correctly identify WebP, so the Resource file failed to be loaded. It is preliminarily determined that there is no solution at present, so we can only reluctantly give up this optimization scheme.

So much for the first goal, image resource optimization.

3.4 Code Optimization

The second goal has been achieved, and the third goal, code optimization, is sorted out as follows:

1. Enable proGuard code optimization

Will proguardFiles getDefaultProguardFile (‘ proguard – android. TXT), ‘proguard – project. TXT

proguardFiles getDefaultProguardFile(‘proguard-android-optimize.txt’),’proguard-project.txt’

Please refer to the appendix for attention after enabling code optimization.

2. Remove useless libraries

If the lowest version apK supports is API14 and no API higher than API14 is used in your code, consider removing the entire Android Support library.

3. Use smaller libraries instead

If you only use Google stats, don’t integrate the entire Google Play Services, just what you need.

4. Clean up discarded code regularly

Periodically remove useless logic and outdated business function modules, as well as obsolete A/B test code.

5. The business module adopts plug-in framework, and the code is dynamically pulled from the cloud

Plugins, that’s another topic, I won’t go into here.

Apk slimming record final results

10536027Byte compression to4926912byte.Compressed by nearly53%

conclusion

1. Enable resource confusion and resource compression in the script

2. Use 7ZIP instead of ZIP

3.gradleEnable code obfuscation optimization and useless resource deletion in scripts

4. For smaller images, use a compression tool to reduce the image size

5. Remove useless resources, languages, local SO libraries, two-party libraries, and resolutions

6. Use smaller libraries

7. Try kicking the Android Support library out of your project entirely

8. Clean up your code regularly

9. Try to use H5 to write the interface and get pictures from the cloud

10. Try plug-in business modules

11. Find all files in the zip folder that are stored as stores (not just in the raw directory) and try to compress and load these resources in an alternative way

12.  trywebpImage loading solutions, looking for breakthroughs

Finally, continue to learn and try new optimization schemes

With this document give “only thin body and product cannot live up to” technology people!!