android代码混淆

来源:互联网 发布:mac用什么软件清理垃圾 编辑:程序博客网 时间:2024/06/18 04:54

一、

都知道在build.gradle中设置如下代码即可开启混淆。

    buildTypes {        release {            minifyEnabled true            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }
其中minifyEnabled为true时即开启混淆,而proguardFiles则指定了混淆规则的文件们,也就是代码会根据proguard-android.text和proguard-rules.pro里所写的规则来进行混淆。你也可以像下面这样进行混淆(只要你在这个文件里设置了混淆规则):

            minifyEnabled true            proguardFiles getDefaultProguardFile('proguard-android.txt')//在proguard-android.txt文件//设置了混淆规则
那么proguard-android.txt文件在哪?就在你的sdk路径下的\tools\proguard文件夹里。

可以发现这儿有三个可疑文件,proguard-android.txt就是默认混淆文件,proguard-android-optimize.txt就是比proguad-android.txt多指定了压缩级别,而proguard-project.txt给我们一条建议:应该保证类中所有js方法不被混淆,这里使用关键词keepclassmembers。

# If your project uses WebView with JS, uncomment the following# and specify the fully qualified class name to the JavaScript interface# class: -keepclassmembers class fqcn.of.javascript.interface.for.webview {   public *; }

二、

新建一个工程,即使你不指定混淆规则文件也能成功打包,如下:

    buildTypes {        release {            minifyEnabled true        }    }
那么我们什么时候不能成功打包?只要设置以下混淆规则就能成功打包。

-dontoptimize-dontpreverify-ignorewarnings
但是通常一打开应用就会崩。而且不推荐使用-ignorewarnings,推荐dontwarn。

三、

对于第三方包,首先肯定是按照其说明配置混淆规则,而如果你按照其说明仍然报错,首先可以放弃使用。其次,如果非要使用的话,报错信息与下面类似

Warning:retrofit2.Platform$Java8: can't find referenced class java.lang.invoke.MethodHandles$LookupWarning:retrofit2.Platform$Java8: can't find referenced class java.lang.invoke.MethodHandleWarning:retrofit2.Platform$Java8: can't find referenced class java.lang.invoke.MethodHandlesWarning:retrofit2.Platform$Java8: can't find referenced class java.lang.invoke.MethodHandleWarning:retrofit2.Platform$Java8: can't find referenced class java.lang.invoke.MethodHandles$LookupWarning:retrofit2.Platform$Java8: can't find referenced class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirementWarning:there were 8 unresolved references to classes or interfaces.Warning:Exception while processing task java.io.IOException: Please correct the above warnings first.Error:Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.> Job failed, see logs for details
出现Please correct the above warnings first,而上面warning是can't find referenced class xxxxxxxx,可以观察前面的retrofit2,即可设置-dontwarn retrofit2来避免报错不能打包。

四、

参考点击打开链接


移除是指在压缩(Shrinking)时是否会被删除。


保持元素不参与混淆的规则如下:

[保持命令] [类] {    [成员] }

“类”代表类相关的限定条件,它将最终定位到某些符合该限定条件的类。它的内容可以使用:

  • 具体的类
  • 访问修饰符(publicprotectedprivate
  • 通配符*,匹配任意长度字符,但不含包名分隔符(.)
  • 通配符**,匹配任意长度字符,并且包含包名分隔符(.)
  • extends,即可以指定类的基类
  • implement,匹配实现了某接口的类
  • $,内部类

“成员”代表类成员相关的限定条件,它将最终定位到某些符合该限定条件的类成员。它的内容可以使用:

  • <init> 匹配所有构造器
  • <fields> 匹配所有域
  • <methods> 匹配所有方法
  • 通配符*,匹配任意长度字符,但不含包名分隔符(.)
  • 通配符**,匹配任意长度字符,并且包含包名分隔符(.)
  • 通配符***,匹配任意参数类型
  • ,匹配任意长度的任意类型参数。比如void test(…)就能匹配任意 void test(String a) 或者是void test(int a, String b) 这些方法。
  • 访问修饰符(publicprotectedprivate

我们再看看proguard-android.txt里写了啥

1、

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native-keepclasseswithmembernames class * {    native <methods>;}

不混淆native的方法

2、

# keep setters in Views so that animations can still work.# see http://proguard.sourceforge.net/manual/examples.html#beans-keepclassmembers public class * extends android.view.View {   void set*(***);   *** get*();}

不混淆继承View的所有类的set和get方法

3、

# We want to keep methods in Activity that could be used in the XML attribute onClick-keepclassmembers class * extends android.app.Activity {   public void *(android.view.View);}

不混淆继承Activity的所有类的中的参数类型为View的方法

4、

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}
不混淆枚举类型的values和valueOf方法

5、

-keepclassmembers class * implements android.os.Parcelable {  public static final android.os.Parcelable$Creator CREATOR;}
不混淆继承Parcelable的所有类的CREATOR

6、

-keepclassmembers class **.R$* {    public static <fields>;}
不混淆R类中所有static字段

7、这是和build版本相关的内容

# The support library contains references to newer platform versions.# Don't warn about those in case this app is linking against an older# platform version.  We know about them, and they are safe.-dontwarn android.support.**# Understand the @Keep support annotation.-keep class android.support.annotation.Keep-keep @android.support.annotation.Keep class * {*;}-keepclasseswithmembers class * {    @android.support.annotation.Keep <methods>;}-keepclasseswithmembers class * {    @android.support.annotation.Keep <fields>;}-keepclasseswithmembers class * {    @android.support.annotation.Keep <init>(...);}
五、

我们有那些东西不能被混淆呢?

1、实体类

2、与js互调的类

3、与反射相关的类

4、如果需要使用类名调用,则不应被混淆

六、

使用注解来保持元素。

在SDK\tools\proguard下还有一个examples文件夹比较可疑。进去后除了一些混淆案例,在SDK\tools\proguard\examples\annotations\src\proguard\annotation文件夹下有一些java类。


如果想通过注解使set和get方法不被混淆

S1、在你的工程中参照KeepPublicGettersSetters.java新建一个类。

package proguard.annotation;//改为你的包名import java.lang.annotation.*;//安卓中不需要导lang下的包/** * This annotation specifies to keep all public getters and setters of the * annotated class from being shrunk, optimized, or obfuscated as entry points. */@Target({ ElementType.TYPE })@Retention(RetentionPolicy.CLASS)@Documentedpublic @interface KeepPublicGettersSetters {}
S2、参照SDK\tools\proguard\examples\annotations\lib文件,在proguard-android.pro文件中添加如下语句

    -keepclassmembers @你的类名 class * {    void set*(***);    void set*(int, ***);    boolean is*();    boolean is*(int);    *** get*();    *** get*(int);    }
S3、参照SDK\tools\proguard\examples\annotations\examples文件,在你需要保持get和set方法不混淆的类的类名上添加@KeepPublicGettersSetters

这样就通过注解完成keep了。

原创粉丝点击