SHRINK APPS WITH GRADLE FOR-ANDROID

原文

SHRINK APPS WITH GRADLE FOR ANDROID

通过Gradle构建工具压缩Android应用

作者:David Tiago Conceição

译者:Waylan Punch

It is almost impossible to write a good Android App without using many libraries. Several features like networking, image loading, caching, database operations, social networking and many others can be very easily incorporated with libraries from different sources. That makes development much easier and faster, but also bring some consequences.

要编写出好的Android应用程序,需要使用许多库文件。有些功能,如网络连接,图像加载,缓存,数据库操作,社交网络等等,可以与不同源的库文件很轻易地结合使用。这使得开发更加容易和快捷,同时也带来了一些后果。

The problem

Every library added to a project brings many possibilities and features. To achieve that, the libraries usually contain a lot of code files and resources. Almost every library I use contain more features than what I need. That creates a sort of waste: my applications have a lot of stuff that are never actually used. More than that, the size of the packages is growing in a fast pace. One of the apps I have been working reached 6.5MB recently. That’s a lot, I can do better.

问题

每一个加载到项目中的库文件会带来了许多可能性和功能。为了实现这些功能,库文件通常包含大量的代码文件和资源。几乎每一个我使用的库文件都包含了更多我用不到的特性。这就造成了一种浪费:我的应用程序有很多的东西都没有在程序中使用到。不止如此,包文件的大小其实增长的很快。我最近开发的一个APP达到6.5MB。这就有点大了,我可以压缩一些。

That’s a big apk.

That’s a big apk.(太大)

Enters Gradle

The Android plugin for Gradle has some nice features to improve the applications. One of those is the option to minify the source code. With this option enabled, the source code will be decreased by the reduction of the identifiers and deletion of unused parts. The source will also be obfuscated, making harder do read if it gets decompiled. Let’s enable it on the build.gradle.

进入Gradle构建工具

Gradle的Android插件有一些不错的功能,可以改善应用程序。其中之一就是缩小的源代码的大小。启用该选项后,源代码将通过减少不必要的标识符和删除未使用的部分减小尺寸。也可以通过这个插件混淆代码,使得源代码在被反编译后更难阅读。接下来我们在build.gradle文件中启用此功能。

//...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
//...

The result is a 6.0MB apk. That’s a good start.

build之后大小变成6.0MB。效果还不错。

A bit better.

A bit better.(稍微小了点)

Resource Shrink

Another cool option from Android Gradle is the resource shrink. When this option is enabled, unused resources are removed from the final apk, reducing it’s size. Let’s enable it:

资源压缩

Android的Gradle插件另一个很酷的功能是资源文件的压缩。当启用该功能之后,未使用的资源文件将从最终的apk文件中删除,以减小apk的大小。接下来我们实际运用一下:

release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}

The result is, well, disappointing.

结果有点令人失望。

No changes in file size.

No changes in file size.(大小没有改变)

Reading a little further in the resource shrink technical doc, there are some options to make the shrink more aggressive. In the case of the application I am working, the option resConfigs did a very good job. By creating a list of the resources configuration used by the application, the tool can eliminate more things.

我们再来深读一下Android官网上关于资源压缩的技术文档,还有一些选项可以进一步压缩。以我开发的这个App为例, resConfigs选项产生了很好的效果。通过创建应用程序所使用的资源配置的列表,该工具可以削减更多的东西。

resConfigs "en", "pt"
resConfigs "nodpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"

Better now.

Better now.(稍小了一些)

By decreasing source code size and removing unused resources, the apk was reduced from 6.5MB to about 5MB. That’s a good improvement.

通过减小源代码的尺寸和删除未使用的资源,我将APK从6.5MB减少到大约5MB。这是一个极大的提升。

But not that fast

One of the reasons that make some people disable the minify option and, by consequence, the shrink option is that it can create runtime issues. In the case of my application, gson wasn’t enable to convert the JSON data returned by the server. To make that work, I had to add a big set of the instructions to my proguard-rules.pro file. The initial set can be found at the gson repository. To complete the set, I had to make the tools ignore (or keep) the classes used with gson:

先别急着乐

从某种意义上来讲,压缩功能会导致运行时异常,这就是禁止开发者启用压缩选项的原因之一。以我的App为例,GSON没法转换从服务器返回的JSON数据。为了使GSON工作,我不得不在proguard-rules.pro文件中添加一系列的指令集。初始设置可以在GSON库中找到。为了完成设置,我不得不让这些工具忽略(或保留)使用到的GSON类:

-keep class com.package.model.** { *; }

The libraries also have it’s own configurations. Glide has the instructions detailed in their page. Okio, that is used in a indirect way, works ignoring the warnings:

库文件也有自己的配置。Glide在他们的主页有详细说明。Okio,以一种间接的方式,忽略警告来工作:

-dontwarn okio.**

SnappyDB is more tricky:

SnappyDB更棘手:

-dontwarn sun.reflect.**
-dontwarn java.beans.**
-keep,allowshrinking class com.esotericsoftware.** {
   <fields>;
   <methods>;
}
-keep,allowshrinking class java.beans.** { *; }
-keep,allowshrinking class sun.reflect.** { *; }
-keep,allowshrinking class com.esotericsoftware.kryo.** { *; }
-keep,allowshrinking class com.esotericsoftware.kryo.io.** { *; }
-keep,allowshrinking class sun.nio.ch.** { *; }
-dontwarn sun.nio.ch.**
-dontwarn sun.misc.**

-keep,allowshrinking class com.snappydb.** { *; }
-dontwarn com.snappydb.**

In the end, there is no choice besides searching for the specific configurations to each library. The point here is to pay attention to each of those configurations. One of the suggestions to make SnappyDB work recommended to disable the resource shrink. That’s is something that won’t happen :) Every time you change one of those options, check the final size again and look for potential runtime errors.

最后,除了为每个库文件搜索特定的配置,别无其他捷径。其中的关键是要注意每个配置。为了使SnappyDB工作,我的建议是,禁用资源收缩功能。这是不可能的事情:) 每次你更改某些配置之后,要检查一下apk文件的最终大小,然后再寻找潜在的运行时错误。

Going further

The apk size probably can be more compressed. At some moment I will go deeper, following the instructions presented by Cyril Mottier in his blog. That will certainly takes more time than adjusting some build files as I did. The result from the adjusts in build files, in the other hand, was very good. Removing 1.5MB of unused stuff from your final APK is certainly a good thing. From now on, minify and shrink configurations are my default choices and will certainly be very savy.

未来展望

APK大小应该能进一步压缩。有时我会按照Cyril Mottier在他的博客里的指导作更深的研究。这肯定会花费多一些时间来调整一些构建文件。调整构建文件的结果从某方面来讲,还是非常不错的。从最终的apk文件中删除了1.5MB的资源文件肯定是一件好事。从现在开始,压缩配置会是我的默认操作,肯定会很牛逼。

Some rights reserved by the author.

作者拥有本文部分版权

TAGs : Android, Gradle, Android Development

I Don't Want Your Money, I Want Aragaki Yui.