Performance Optimization Series
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
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:keep
specify each resource you want to keep the property in tools:discard
designated 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.xml
file. 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.png
the 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.xml
the files shrinkMode
set as strict
follows:
<?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:keep
the 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
- The larger volume projects, more resources, more noticeable results.
- Link deleted using the resource, we must be cautious, ahead of the backup.
- 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