alwaystest / Blog

24 stars 2 forks source link

Android代码混淆 #39

Open alwaystest opened 7 years ago

alwaystest commented 7 years ago

Android代码混淆

标签(空格分隔): Android


不论是为了代码安全性,还是临时解决64K问题, 代码混淆实在是 Android上避不过的坑。说是代码混淆,其实除了混淆,Proguard还提供了代码优化,移除无用代码等功能。

我主要用到的是移除无用代码和混淆的功能。

通常情况

Android Studio启用代码混淆很简单,通常情况下只要配置android application的build.gradle文件为以下格式即可:

android {
    ...
    buildTypes {
        release {  //配置release版本
            minifyEnabled true //开启代码混淆
            // 从sdk/tools/proguard/proguard-android.txt文件读取默认的混淆规则,与当前配置Module下的proguard-rules.pro中的规则一同使用,proguard-rules.pro的文件名字可以修改,如果没有这个文件,需要手动新建一个
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  
        }
    }
}

特殊情况

特殊情况是当使用Android Library时,library的混淆规则不能按照上面的方法配置。参照StackOverflow http://stackoverflow.com/questions/26983248/proguard-ignores-config-file-of-library

只需要指定library的build.gradle文件中

android{
    ...
    defaultConfig {
        consumerProguardFiles 'proguard-rules.txt'
    }
}

当Application配置开启混淆的时候,library就会读取library目录下的proguard-rules.txt规则来进行混淆。library不需要指定minifyEnabled true

有些aar格式的依赖库在发布的时候就可能做了这些,参考http://blog.csdn.net/lihenair/article/details/51671803


一般在使用了第三方库的时候,网上有现成的混淆规则可以拿来用,但是复制粘贴的时候要注意从网页复制出来的东西可能编码有问题,比如我就碰到一个

ProGuard configuration parser error: D:\coding...\proguard.txt line 38:20 no viable alternative at character '?'

混淆规则是从网页复制粘贴进来的。有一个字母是异常字母,所以报错。

配置混淆规则,不想看大段Proguard英文文档的,入门可以先看看汉化,理解之后,细节问题再去官方文档里面查。

一定要记得保存发布时Proguard生成的文件,混淆后,会在/build/proguard/目录下输出下

开启混淆后出现问题的,我用一种比较笨的办法解决。

根据运行时方法的错误提示,打开Proguard生成的文件,查看usage.txt,确认代码压缩过后有没有被删除,查看mapping.txt,确认代码混淆过后类名,方法名,变量名是否符合预期。根据结果调整混淆规则。


我使用代码压缩主要解决的是64k问题,但是Instant Run功能和无法和Proguard 共同工作。而且即便不使用Instant Run,混淆代码需要消耗时间,混淆过的代码不方便Debug,也都是问题。

幸运的是我发现了这个: http://www.jianshu.com/p/30ef794ca4e7

Gradle plugin 2.0 新增了 built-in code shrinker(内置代码压缩)用来取代 ProGuard(一般用在 debug build),它只会压缩(shrink)代码而不会混淆(obfuscate),能够进一步加快 Instant Run 的运行速度。 开启方法是添加 useProguard false 到 build.gradle 文件里

android {
    buildTypes {
        debug {
            minifyEnabled true
            useProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt')
        }
        release {
            minifyEnabled true
            useProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt')
        }
    }
}

其他参考文章:

Shrinker https://edhroyal.com/post/10.android-studio-2.1/