Performance Optimization (xii) APK limit compression (more resources, the effect is more significant)

Performance Optimization Series

APP start optimization

UI rendering optimization

Memory Optimization

Image Compression

Long graph optimization

Power optimization

Dex encryption and decryption

Dynamic replacement Application

Thermal stability of the repair principle explore APP

Continuous operation of the APP process keep alive achieve

ProGuard compress the code and resources

APK limit compression

Brief introduction

With the continuous iteration of the project, the amount of code with the resource file continues to grow. APK file then there will be more and more packaged, if suddenly one day you call your boss or leader to optimize APK size, you do not know how to optimize it would not be justified, we will go together to analyze and optimize this article APK volume size of it.

APK resource consumption analysis

note:

I was looking for a GitHub relatively high popularity of open-source projects, if required, you can click to download , try something yourself.

AS Build analysis tools directly used / Analyze APK

Draw assets> classes.dex> res> From the above figure lib where the resource files are taking up the most.

Here we take a look at how to reduce the size of it APK,

APK eight big volume optimization

1. convert the picture format webp

Webp concept

WebP is a lossy compression while providing lossless compression of image file format, derived from VP8 video encoding format. WebP originally released in 2010, aims to reduce the file size, but to achieve the same quality JEPG format images, hoping to reduce the transmission time of image files on the network. November 8, 2011, Google started to make WebP support lossless compression and transparent color function.

According to Google earlier test, WebP lossless compression less than 45 percent of the file size of the PNG file found on the network, even if they use PNG files in PNGCRUSH and PNGOUT treated, WebP still can reduce file size by 28%. For now, Webp can make an average 70% reduction in the size of the picture. WebP image format is the future trend of.

PNG / JPG to Webp

Click on the image or folder, right-select Convert to Webp format, png / jpg picture compression format is webp picture.

Finally, we only reduced by about less than 200 kb, it is possible to project images resources already not much, just too much due to the small picture.

Scenarios and advantages

  • Client software, embedded on the Chromium webview, this type of web browser application that can fully use the WebP format, enhance rendering speed load, regardless of compatibility.
  • Node-webkit program development, the volume can be reduced using WebP file package.
  • Mobile application or web games, the interface requires a lot of pictures, you can embed WebP Codec Pack, users can save traffic, improve access speed advantage:
  • For PNG images, WebP 45% smaller than PNG.

2. Remove multi-language

In the app / build.gradle add

android{
    ...
    defaultConfig{
        ...
        //只保留英语
        resConfigs "en"
    }
}
复制代码

Here we find reduced about 200 kb

3. Remove unnecessary so library

Micro-channel version that decompile Android, micro-channel only fit the armeabi-v7a architecture, we support other libraries delete it.

android{
    ...
    defaultConfig{
        ...
            ndk {
            //设置支持的SO库架构
            abiFilters "armeabi-v7a"
     }
}
}

复制代码

And optimize the almost 600 kb, continue.

4. Remove unnecessary resources Link check (caution deleted)

concept

Lint is scanning the code analysis tools provided by Android Studio, it can help us find the code structure / quality issues, while offering some solutions, and this process does not require us handwriting test. Code iterative version over one, it is easy to leave behind unused code, resource files, we can use the Lint cleared.

How to check the Link

AS open tools, find Analyze> Run Inspection By Name> unused resources

optimization

We optimized the link found about 700 kb continue.

note

Because the link is to check there is no reference to do to determine whether the use of resources, so if this is the way to Le, so when deleted must be cautious.

//动态获取资源 id , 未直接使用 R.xx.xx ,则这个 id 代表的资源会被认为没有使用过(类似不能混淆反射类)
int indetifier =getResources().getIdentifier("img_bubble_receive", "drawable", getPackageName()); getResources().getDrawable(indetifier);

复制代码

5. Turn confusion

If there is confusion not know what I can suggest to look at the article again on performance optimization (XI) ProGuard compress the code and resources

1.7M optimized probably continue.

6. Removing unused resources shinkResource

  • Open shinkResource = true

        buildTypes {
            release {
                minifyEnabled true
                shrinkResources = true
    
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
            debug {
                shrinkResources = true
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    复制代码

The possible link to delete the useless resources, so there is no optimization at the

7. Turn delete unnecessary resources (strict mode and normal mode) - that I can not test here, you can test the effect of down under

Normal mode is the custom mode

If you want to keep or discard a particular resource, create your project contains a <resources>XML file marks, and tools:keepspecify each resource you want to keep the property in tools:discarddesignated each resource to abandon the property. Both attributes accept a comma-separated list of resource names. You can use the asterisk as a wildcard character.

E.g:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />
复制代码

Save the file in the project resources, for example, saved res/raw/keep.xml. Construction of the file will not be packaged into the APK.

Specifies the resource you want to discard may seem silly, because you could have them removed, but in the use constructs variants, this may be useful. For example, if you knowingly given on the surface of the resources will be used in your code (and therefore will not be removed compressor), but the actual building will not be used for a given variant, you can put all the resources into a common project directory, then create a different build variants for each keep.xmlfile. Build tools may not correctly identify the resources required, since the compiler adds inline resource ID, rather resource analyzer may not know the difference between the reference integral value real resources and code happens to have the same value in the.

Strict Mode

Under normal circumstances, the resource compressor system can accurately determine whether the use of resources. However, if your code calls Resources.getIdentifier()(or any of your library this call - AppCompat library performs the call), which means that your code will be based on the name of the query string resources dynamically generated. When you perform this call, the default resource compressor will take defensive actions, all resources tagged with a matching name for the format may have been used, can not be removed.

For example, the following code will bring all img_prefixes resources marked as used.

String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());
复制代码

Resource compressor also browse the code as well as a variety of res/raw/all string constants resources to find a format similar to file:///android_res/drawable//ic_plus_anim_016.pngthe resource URL. If it finds a string of similar thereto, or find other strings can be used to build its seemingly similar URL will not remove them.

These are examples of security enabled by default compression mode. However, you can disable this "be prepared" approach, and specified resource compressor retaining only the resources that have been used to determine. To perform this, in keep.xmlthe files shrinkModeset as strictfollows:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:shrinkMode="strict" />
复制代码

If you are indeed stringent compressed mode is enabled, and also refers to the code resource (as shown above) comprising dynamically generated string must use tools:keepthe attribute manually retain these resources.

8. The AndResGuard micro channel resource compression scheme

What is AndResGuard

AndResGuard is a tool to reduce the size of APK, its principle is similar to Java Proguard, but only for resources. It will otherwise redundant resource path is shortened, for example res / drawable / wechat becomes r / d / a.

Why AndResGuard

In the past development, we usually only confuse code, resource file was exposed in front of others, readability res folder all file names too strong.

The effect of after use

AndResGuard configuration

  • Build.gradle project root directory, add the dependent plug-ins:

     dependencies {
            classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.16'
        }
    复制代码
  • In the app directory, create and_res_guard.gradle file

apply plugin: 'AndResGuard'

andResGuard {
    mappingFile = null
    use7zip = true
    useSign = true
    keepRoot = false
    compressFilePattern = [
            "*.png",
            "*.jpg",
            "*.jpeg",
            "*.gif",
            "resources.arsc"
    ]
    whiteList = [
            // your icon
            "R.drawable.icon",
            // for fabric
            "R.string.com.crashlytics.*",
            // for umeng update
            "R.string.tb_*",
            "R.layout.tb_*",
            "R.drawable.tb_*",
            "R.drawable.u1*",
            "R.drawable.u2*",
            "R.color.tb_*",
            // umeng share for sina
            "R.drawable.sina*",
            // for google-services.json
            "R.string.google_app_id",
            "R.string.gcm_defaultSenderId",
            "R.string.default_web_client_id",
            "R.string.ga_trackingId",
            "R.string.firebase_database_url",
            "R.string.google_api_key",
            "R.string.google_crash_reporting_api_key",

            //友盟
            "R.string.umeng*",
            "R.string.UM*",
            "R.layout.umeng*",
            "R.drawable.umeng*",
            "R.id.umeng*",
            "R.anim.umeng*",
            "R.color.umeng*",
            "R.style.*UM*",
            "R.style.umeng*",

            //融云
            "R.drawable.u*",
            "R.drawable.rc_*",
            "R.string.rc_*",
            "R.layout.rc_*",
            "R.color.rc_*",
            "R.id.rc_*",
            "R.style.rc_*",
            "R.dimen.rc_*",
            "R.array.rc_*"
    ]

    sevenzip {
        artifact = 'com.tencent.mm:SevenZip:1.2.10'
    }
}

复制代码
  • build.gradle file in the app module added

    apply from: 'and_res_guard.gradle'
    复制代码
  • After finished packing renderings

Resources compressed about 1M

to sum up

  1. The larger volume projects, more resources, more noticeable results.
  2. Link deleted using the resource, we must be cautious, ahead of the backup.
  3. Because here just over 10 M project itself, finally optimizes the 4.5 M down. It is still not easy.

Reproduced in: https: //juejin.im/post/5d0627f7f265da1bd4247e76

Guess you like

Origin blog.csdn.net/weixin_33774615/article/details/93167235