Android混淆注意事项

刚开始项目中需要加入混淆时候,不知道从何开始。各种查资料,然后就是一头雾水不知道什么事是正确的。没有少折腾,其实混淆还是挺简单的,用之前还是要老老实实的看一下官方的文档。大致知道代码压缩混淆,资源压缩是个什么意思。

下面就是官方的两个文档,一个说明文档,一个Proguard使用手册:

https://developer.android.com/studio/build/shrink-code.html

https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/introduction.html


官方文档中有几个要点:

1.Android studio 中如何添加混淆

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

proguardFile的解释(除了默认的混淆规则文件,我们需要定义的新规则在proguard-rules.pro文件中)

除了 minifyEnabled 属性外,还有用于定义 ProGuard规则的 proguardFiles 属性:

·getDefaultProguardFile('proguard-android.txt') 方法可从 Android SDK tools/proguard/ 文件夹获取默认的 ProGuard设置。

提示:要想做进一步的代码压缩,请尝试使用位于同一位置的 proguard-android-optimize.txt 文件。它包括相同的 ProGuard 规则,但还包括其他在字节码一级(方法内和方法间)执行分析的优化,以进一步减小 APK大小和帮助提高其运行速度。

·proguard-rules.pro 文件用于添加自定义 ProGuard规则。默认情况下,该文件位于模块根目录(build.gradle 文件旁)。


2.哪一些不能进行代码混淆的

  • 当应用引用的类只来自 AndroidManifest.xml 文件时(Android 四大组件)
  • 当应用调用的方法来自 Java 原生接口 (JNI) 时(虽然默认规则中通过native方法过滤排查一部分,但是动态注册在C层的类和方法是需要重新排查一下)
  • 当应用在运行时(例如使用反射或自检)操作代码时(反射方法,和Class的使用  eg:a instanceof a.Class)


3.加入混淆之后如何进行问题定位(保留输出文件)

每次构建时 ProGuard 都会输出下列文件:

dump.txt

说明 APK 中所有类文件的内部结构。

mapping.txt

提供原始与混淆过的类、方法和字段名称之间的转换。

seeds.txt

列出未进行混淆的类和成员。

usage.txt

列出从 APK 移除的代码。

这些文件保存在 /build/outputs/mapping/release/ 中


以下是自己使用中觉得需要注意学习的地方:


1.需要知道基本通配符的使用和混淆规则关键字(以下来自于Proguard使用手册的翻译)

a.类的通配符介绍:

? 匹配类名称中的任何单个字符,但不匹配包分隔符。例如,“mypackage.Test?”比赛”mypackage.test1”和“mypackage.test2”,而不是“mypackage。test12”。

* 匹配不包含包分隔符的类名称的任何部分。例如,“mypackage.*Test*“比赛”mypackage.Test”和“mypackage。yourtestapplication”,而不是“mypackage.mysubpackage.MyTest”。或者,更普遍的是,“mypackage.*”比赛中所有的类“mypackage”,但不在其子包。

** 匹配类名称的任何部分,可能包含任意数量的包分隔符。例如,“**.Test”匹配所有包中除根包之外的所有测试类。或者,“mypackage.**”匹配中所有的类“mypackage”及其子包。

b.类中方法通配符:

   匹配任何构造函数

  匹配任何字段

 匹配任何字段或方法

*        任何字段或方法

c.方法名称通配符:

? 匹配方法名中的任何单个字符。

* 匹配方法名的任何部分。


d.方法参数的通配符:

%匹配任何原始类型(“布尔”、“int”等),但不匹配“空”。

?匹配类名中的任何单个字符。

*匹配不包含包分隔符的类名称的任何部分。

**匹配类名称的任何部分,可能包含任意数量的包分隔符。

***匹配任何类型(原始的或非原始的、数组或非数组)。

...匹配任意类型的任意数量的参数


e:常用的混淆关键字:

-keep {Modifier} {class_specification} 保护指定的类文件和类的成员

-keepclassmembers{modifier}{class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好

-keepclasseswithmembers{class_specification}保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。

-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)

-keepclassmembernames {class_specification}保护指定的类的成员的名称(如果他们不会压缩步骤中删除)

-keepclasseswithmembernames{class_specification}保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)

-keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable,LocalVariableTable,SourceFile, Deprecated, Synthetic, Signature, andInnerClasses.


2.一些混淆方法举例的使用(Proguard给的很详细:https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/examples.html)

a.如何不混淆指定的方法(比如该方法是反射方法或者JNI动态注册调用的方法)

参考:http://www.cnblogs.com/renhui/p/5863199.html

b.下面是常见的混淆规则需要知道区别:

-keepnames class packagename.**
-keep class packagename.**
-keep class packagename.** {*;}


 

3.因为项目是个混合应用,使用到了Cordova和Crosswalk三方库。下面给出相关混淆代码:

#cordova
-keep class org.apache.cordova.**{*;}
-keep public class *extendsorg.apache.cordova.CordovaPlugin
#XWalk官方提供
-keep class org.xwalk.core.** { *; }
-keep class org.chromium.** { *; }
-keepattributes **
#如果有警告需要移除以下几个警告
-dontwarn android.view.**
-dontwarn android.media.**
-dontwarn org.chromium.**


 
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(Android代码混淆)