煎饼

煎饼为你分享Android有关的技术文章
不断分享,点滴积累,共同提高

关注微信公众号[developers]
更快的了解新的技术动态

ProGuard With Gradle

在官方Android开发者文档中有一篇很nice的文章why you should use Proguard when you building your application.但是文档还没有涉及到新的Gradle构建系统。

Android的Gradle构建系统有一个内置的任务来运行ProGuardAndroid Tools site有关ProGuard的内容只有一小部分,重要的细节都没有讲出来。

对于一个特别的 BuildType 要打开ProGuard任务,只要设置minifyEnabled的值为true就可以了。默认情况下,debug build type的ProGuard是关闭的(minifyEnabled false),这点大家都很清楚。

接下来使用两个默认Android文件中的一个作为ProGuard的基本配置文件。如果你的Android项目已经很久了,你的基本配置文件估计也该更新了.新的文件运行的会更好,下面两个文件,保守的选择是non-optimized那个文件,optimized文件会带来意想不到的麻烦。

1
2
3
proguardFile getDefualtProguardFile('proguard-android.txt') 
//or
proguardFile getDefualtProguardFile('proguard-android-optimized.txt')

为项目添加所需要的ProGuard规则,我个人比较喜欢把每个library的ProGuard规则单独的放一个文件,这样我就可以在不同的项目中复用了。这些文件的最简单放置位置是在Project的最顶层,也就是和build.gradle文件同一级(添加到项目默认的地方就好了)。我在GitHub上开始收集常用的Libraries的ProGuard Files.当从一个项目中不在使用某种依赖库时,使用这种方法就可以很容易的移除相关ProGuard的配置,非常方便。

1
2
proguardFile 'proguard-google-play-services.txt'
proguardFile 'proguard-gson.txt'

另外我们还需要为项目中一些比较明确的地方添加一个模糊的ProGuard配置文件,比如:所有需要使用Gson解析的类就需要使用这样的规则。

1
2
-keep class com.jabin.sample.BuildConfig {*;}
-keep class com.jabin.sample.model.User {*;}

把所有的文件放在一块,基本的ProGuard配置就和下面相似了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
android {
    ...
    buildTypes {
        debug{
            debuggable true
            minifyEnabled false
        }
        release {
            debuggable false
            minifyEnabled true
            proguardFile 'proguard-bugsense.txt'
            proguardFile 'proguard-eventbus.txt'
            proguardFile 'proguard-google-play-services.txt'
            proguardFile 'proguard-gson.txt'
            proguardFile 'proguard-project.txt'
            proguardFile getDefaultProguardFile('proguard-android.txt')
        }
    }
}

还有一个点需要注意,一定要保存每次在release下build产生的mapping.txt文件,这个文件保存了混淆前后的信息,它在/build/{appname}/proguard/{buildvariant}目录下。你可以把它上传到异常捕获平台(Umeng,BugSense,Crashlytics,etc)去分析崩溃日志,会有很大帮助。

另外,作为一个Android应用开发者,你会使用ProGuard去混淆、优化、缩减你的应用,但是在build release version时,它往往会花费一段令我们头疼的时间,如果你的Project过大的话。这时我想你有必要了解一下Squad Leader库,它让这个步骤更简单。Squad leader包含两个注解(Annotation):@Keep & @Keepname,你可以讲这个两个注解添加到class、 method 或者 field,但@KeepName注解的对象是一定要被使用的,如果你不确定这个对象会不会被使用,那可以用@Keep来注解。

dependencies {
    compile 'nl.littlerobots.squadleader:squadleader:<latest-version>'
}

引入包后,就可以通过注解合适的class,field or method 来注解那些你不想使用ProGuard来处理的对象。Example:

import nl.littlerobots.squadleader.Keep;
import nl.littlerobots.squadleader.KeepName;

public class Example {
    @KeepName
    // this field will be stripped if it's unused in your code
    public String stringTheory;
    @Keep
    // this field will be kept, even if it's unused
    public boolean myBool;
}

或者

@Keep
// this class is not stripped or obfuscated
public class Example {
    public String stringTheory;
    public boolean myBool;
}

这个与ProGuard之间没有影响,在build relaese version时,ProGuard还是会作用于其他libraries。更详细的信息请看Squad leader

266

分享本文:

Dagger on Android-基础篇