~ Android package size optimization performance optimization combat

Outline

Users typically are not willing to download a larger program, especially in the case of not WIFI. If your package is small, users are still willing to download and install experience under. Now available in App meet certain requirements usually have a lot of money, how to allow users to download your App willing to experience? The smaller installation package, in the case of WIFI, download speed installation, start experience. In the case of mobile networks, the smaller package size, the greater the possibility that the user installed. Therefore, the installation package size has a great impact on the user's conversion rate. Then you and share some of my experiences on package size optimization work in practice.

APK file structure

Since it is to optimize the size of the Android APK installation file, the primary need to understand the structure under the APK file. The APK file dragged AndroidStudio can clearly see the APK file components. APK mainly consists of the following components:

  • INF-META / : The main file folder contains CERT.SF and CERT.RSA signature files, as well as the manifest file MANIFEST.MF
  • Assets / : This folder contains the main asset in the app file, by AssetManager objects in the program to get
  • RES / : The main folder contains no files are compiled into resources.arsc
  • lib / : This folder so library contains some platforms, such as armeabi, armeabi-v7a, arm64- v8a, x86, x86_64, and mips.
  • resources.arsc : This file is mainly kept the resources compiled. The main storage of the contents of the file under res / values directory, the packaging tool to extract the XML contents of the directory (string, style) it compiled into a binary format.
  • classes.dex : This file mainly contains class files can be understood Dalvik / ART virtual machine DEX format
  • AndroidManifest.xml : The main core of the Android manifest document file using Android binary XML format.

Optimization methods

In fact, APK on two core content, pictures and code resources. Therefore, the volume of packet optimization largely from two aspects. Such as checking assetswhether there are unused resources directory. In general rarely put some useless resource directory in assets, mainly integrate third-party SDK (such as High German, Baidu maps, etc.) when the need to put some resources into it, such as images, audio files, etc. With iteration of the project, UI interface style than ever before undergone great changes, so many pictures before the resource will not be available, so resmight not exist a lot of pictures directory, which we did not clean up the most important use of the resources of a folder. In addition to the picture, then that classes.dexfile, and the general program of our own business code does not have a huge impact on package size, mainly the use of a large number of third-party libraries, and some module integrates the company's other team, could these module It contains a lot less than we used code or resources.

Before optimization, installation package size down to see me doing project is 73437KB (71.7MB), is back to do good and to optimize a contrast, look at the specific optimization of amplitude.

Remove unused resources by AndroidStudio

Manually remove resources are two advantages: one is to reduce the volume of the installation package, the other is to reduce the volume of the source code.

There are two ways to help us find unused resources in AndroidStudio in:

  • The Analyze -> the Inspect Code , in fact, by lint tools to help us find unused resources, in addition to pictures of resources, but also help me to find potential problems that exist in the code, run the results as shown below:

    Inspect Code

  • Double-click the Shift , enter Remove Unused Resources, and then press Enter. Due to the above approach not only to identify unused resources, but also detection code, so time-consuming operation. If you just want to find unused resources, you can use double-click shift the way they detect the result is the same.

The above tool has two pits in the use of the process:

  • Use of resources, it is still reported no references. Some resources, such as drawable xml file

  • It also removes a lot of the layout id, if the project uses ButterKnife, R2 is applied by the id, the tool can not detect this

So, for the resources in the drawable directory we can git to revert, because we rarely put the icon drawable directory. For id layout declaration is removed, we can layout folders revert.

By the above operation, reducing the volume of packets successfully 2.3M:

operating volume cut back
Optimization ago 73437KB (71.7MB) -
Inspect Code 71054KB (69.3MB) 2383KB (2.3M)

In the manual removal of unused resources in the process, we discovered another problem. Now are modular project, we have dozens of projects module, the module necessarily contains a lot of system default ic_launcher icon, the new module generated by default, and the icon changed to the name of our project app_icon, which is inside the ic_launcher is not use. Under each module on ic_launcher on 8 folders:

drawable
    -> ic_launcher_background.xml

drawable-v24
    -> ic_launcher_foreground.xml

mipmap-anydpi-v26
    -> ic_launcher.xml
    -> ic_launcher_round.xml

mipmap-hdpi
    -> ic_launcher.png
    -> ic_launcher_round.png

mipmap-mdpi
    -> ic_launcher.png
    -> ic_launcher_round.png

mipmap-xhdpi
    -> ic_launcher.png
    -> ic_launcher_round.png

mipmap-xxhdpi
    -> ic_launcher.png
    -> ic_launcher_round.png

mipmap-xxxhdpi
    -> ic_launcher.png
    -> ic_launcher_round.png

Sometimes, the module may be required launcher, although do not need at the time of publication, but we may need to run the separate components, generally have a debug manifest and release manifest, and then be judged by a mark or a library application. In fact, it can also be used in other ways to the achievement of this debug and release of (the module can coat a layer of engineering project, the project includes this module, can run as an application). In this way, module does not need the presence of the application, it does not require a launcher icon.

In fact, this is also the developer is very easy to ignore the problem, for example, we rely on a lot of other departments within the library, by the ctrl + shift + r Find ic_launcher, will find a lot aar there launcher resources. And even some non-standard third-party open source libraries also these problems.

operating volume cut back
Optimization ago 73437KB (71.7MB) -
Inspect Code 71054KB (69.3MB) 2383KB (2.3M)
Remove Launcher 71035KB (69.3MB) 19KB

Why so many launcher removed the picture, why apk size is only reduced 19KB? (What specific fewer places, can be compared by Compare with previous APK function).

Since the time of the final generation APK, only use a resource file of the same name, that is, there will be only one, so optimizing modest (about the same module multiple paths exist the same name, will be the priority package, we You can view the official documentation ). But we have to clean up some garbage project resources.

Open shrink resource

In fact, in our project app / build.gradle shrink resource configured in the open:

minifyEnabled true
shrinkResources true

We use the icon name of the program is not using ic_launcher, but app_icon, we passed our APK APK Analyze analysis also found ic_launcher resources, on ic_launcher icon name should not be used in the program, why not shrink it? There are two possibilities:

  • There are hidden somewhere uses ic_launcher file.
  • shrink not in force

Let's take a project shrink has not entered into force. I put a new resource (abc.webp) to the project going, then re-packaged, if the file is described shrink shrink is in effect (also indirectly describes the procedures used somewhere in the ic_launcher), if not shrink explained above configuration does not make it shrink into effect, you can find a way to let it take effect.

The new generation APK files APK Analyze open and found the newly added abc.webpfiles still exist:

abc.webp

Description shrink no effect. Obviously it has been configured minifyEnabled, shrinkResources, Why not in force yet.

After a search, the original is set up not to shrink in proguard file:

-dontshrink

This line comments, and then repackaged and found reduced 3.37MB

operating volume cut back
Optimization ago 73437KB (71.7MB) -
Inspect Code 71054KB (69.3MB) 2383KB (2.3M)
Remove Launcher 71035KB (69.3MB) 19KB
ShrinkResources 67576KB(65.9MB) 3459KB (3.37M)

shrinkMode are mainly two: safe, strict, the default mode is safe.

You can be res/raw/keep.xmlconfigured shrinkMode file:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:shrinkMode="safe"/>

If you open the shrink resource, when shrinkMode = safe, packed time will take the initiative to find those resources that may be referenced, such as by way of access to resources resources.getIdentifier (), the resource will not be reduced, when shrinkMode = strict strict mode the resources will not be reduced.

I was doing experiments, we found that if a resource is shrink, and it may still APK in, but the volume of the resource becomes very small.

If you set the shrinkMode safe, it may not have been used also to be preserved, because detection may not be so accurate.

You can shrinkMode set to strict, this time you need to get through resources.getIdentifier (A) how resources keep up. You can configure files to keep in keep.xml in:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:shrinkMode="strict"
	tools:keep="@drawable/ic_get_by_identifier"/>

More confusion about the relevant knowledge, you can view AndroidAll

png turn into webp

Android4.0 began to support webp, but only supports transparency in Android4.3, lossless webp. So if your app supports a minimum of 4.3, you can use webp instead of png.

In AndroidStudio a key support in the conversion, you can select the mass ratio transcoding, you can also choose to turn to if instead of webp bigger than the original png, can be skipped.

operating volume cut back
Optimization ago 73437KB (71.7MB) -
Inspect Code 71054KB (69.3MB) 2383KB (2.3M)
Remove Launcher 71035KB (69.3MB) 19KB
ShrinkResources 67576KB(65.9MB) 3459KB (3.37M)
Png2webp 64505KB (62.9M) 3071KB (3M)

Enable R8

Because before R8 is not very stable, so we will be closed. Now AndroidStudio 3.6, we will open it:

android.enableR8=true

Although official website said R8 ProGuard support existing rule files, but in actual use still some problems, solve the problem of some confusion configuration, again playing a release package and found reduced 0.9M:

operating volume cut back
Optimization ago 73437KB (71.7MB) -
Inspect Code 71054KB (69.3MB) 2383KB (2.3M)
Remove Launcher 71035KB (69.3MB) 19KB
ShrinkResources 67576KB(65.9MB) 3459KB (3.37M)
Png2webp 64505KB (62.9M) 3071KB (3M)
R8 63506KB(62M) 999KB (0.97M)

The above is the normal mode R8, R8 as well as full mode, but also do some additional optimization operation, R8 open full mode, but is still experimental nature:

android.enableR8.fullMode=true

Re playing a release package and found reduced 0.16M:

operating volume cut back
Optimization ago 73437KB (71.7MB) -
Inspect Code 71054KB (69.3MB) 2383KB (2.3M)
Remove Launcher 71035KB (69.3MB) 19KB
ShrinkResources 67576KB(65.9MB) 3459KB (3.37M)
Png2webp 64505KB (62.9M) 3071KB (3M)
R8 63506KB(62M) 999KB (0.97M)
R8 FullMode 63333KB (61.8M) 173KB (0.16M)

Instead of the icon by custom View

We can also replace some status icons, such as order status, refund status by custom View. As follows:

Here Insert Picture Description

These icons are similar can be done using a custom View, you can reduce a lot of pictures resources. If the state a lot, you will need a lot of status icon, if international support, it also needs to generate a corresponding status icon for each country.

After replacement state Custom View icon, reduced package size 0.366M:

operating volume cut back
Optimization ago 73437KB (71.7MB) -
Inspect Code 71054KB (69.3MB) 2383KB (2.3M)
Remove Launcher 71035KB (69.3MB) 19KB
ShrinkResources 67576KB(65.9MB) 3459KB (3.37M)
Png2webp 64505KB (62.9M) 3071KB (3M)
R8 63506KB(62M) 999KB (0.97M)
R8 FullMode 63333KB (61.8M) 173KB (0.16M)
CustomView 62958KB (61.4M) 173KB (0.36M)

Use AndResGuard

Micro-channel use AndResGuard can be confusion about the resources in the resource path and resource name, resource name change to be like abc all the way. It can greatly reduce the space occupied by the name of the character.

Especially after the modular resources in order to prevent the same name, we will add the module prefix resources, thus leading to the name of the resource even longer. When using AndResGuard, the program resources available through getIdentifier way, be sure to whitelist, this may be global find in the program.

通过 AndResGuard 混淆后,包体积减少了 3.54M:

操作 体积 减少
优化前 73437KB(71.7MB) -
Inspect Code 71054KB(69.3MB) 2383KB(2.3M)
Remove Launcher 71035KB(69.3MB) 19KB
ShrinkResources 67576KB(65.9MB) 3459KB(3.37M)
Png2webp 64505KB(62.9M) 3071KB(3M)
R8 63506KB(62M) 999KB(0.97M)
R8 FullMode 63333KB(61.8M) 173KB(0.16M)
CustomView 62958KB(61.4M) 173KB(0.36M)
AndResGuard 59323KB(57.9M) 3635KB(3.54M)

so 文件

在主流的手机CPU架构都是 ARM,基本上只要支持这一种架构就可以了。更多关于这方面的知识可以查看 Android NDK ~ 基础入门指南

我们来看下市面上主流的 app 支付宝和微信的 CPU 架构:

alipay-arm

weixin-arm

armeabi-v7a 是向下兼容 armeabi,arm64-v8a 能兼容 armeabi-v7a 和 armeabi

我们项目中也是只支持一种 armeabi-v7a 架构,减少 so 文件体积大小

release {
    ndk {
        abiFilters 'armeabi-v7a'
    }
    //...
}

小结

到此,就介绍完了我这次包体积优化相关内容了,差不多了减少了 20% 的包体积大小。当然优化是无止尽的,除了上面的一些优化手段还有 app Bundles 的方式(需要结合 Google Play 一起);还可以考虑通过 BackgroundLibrary 替换程序中大量的 shape、selector 文件,减少包体积,但是该库对性能有一定的影响,所以我还没有使用,后面可以考虑是否还有更好的方案;还可以找出程序中重复的图片(图片内容一致,名字不同);当然还有插件化,插件也需要瘦身,减少下发消耗的流量。

Another source article involved in my AndroidAll GitHub repository. In addition to the warehouse 性能优化, as well as Android programmers need to master the technology stack, such as: application architecture, design patterns, performance optimization, data structures, algorithms, Kotlin, Flutter, NDK, and popular open-source framework Router, RxJava, Glide, LeakCanary, Dagger2, Retrofit, OkHttp, ButterKnife, the principles of analysis Router , etc., continuously updated, welcomed the star.

Published 168 original articles · won praise 1161 · Views 1.28 million +

Guess you like

Origin blog.csdn.net/johnny901114/article/details/105189854