混淆

安卓混淆和资源压缩

2019-05-06  本文已影响33人  jiantaocd

Android开发中掌握混淆规则是必备技能之一。

混淆方式

主module中统一配置

这种情况简单,针对自己项目代码和三方库代码编写混淆规则即可。当取消某些module依赖时,需要剔除响应的混淆规则,较麻烦。

各module单独配置

随着项目不断扩大,多个module同时存在的项目已很普遍。

proguard使用及规则

主module开启混淆配置

android {
    ...
    buildTypes {
        release {
              // zipAlign可以让安装包中的资源按4字节对齐,这样可以减少应用在运行时的内存消耗。
              zipAlignEnabled true
            // 压缩资源
            shrinkResources true
            // 开启混淆
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
        }
    }
}

通用规则

#指定压缩级别
-optimizationpasses 5

#不跳过非公共的库的类成员
-dontskipnonpubliclibraryclassmembers

#混淆时采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

#把混淆类中的方法名也混淆了
-useuniqueclassmembernames

#优化时允许访问并修改有修饰符的类和类的成员 
-allowaccessmodification

#将文件来源重命名为“SourceFile”字符串
-renamesourcefileattribute SourceFile
#保留行号
-keepattributes SourceFile,LineNumberTable
#保持泛型
-keepattributes Signature

#保持所有实现 Serializable 接口的类成员
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

#Fragment不需要在AndroidManifest.xml中注册,需要额外保护下
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment


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

# 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*();
}

# 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);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keepclassmembers class * implements android.os.Parcelable {
 # 保持Parcelable不被混淆  
  public static final android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

# 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>(...);
}

# 保持测试相关的代码
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**

哪些需要添加keep规则

自定义规则及语法

-keep public class name.huihui.example.Test { *; }
-keep class name.huihui.test.** { *; }
-keep public class * extends name.huihui.example.Test { *; }
-keep public class **.*model*.** {*;}
-keep class * implements name.huihui.example.TestInterface { *; }
-keepclassmembers class name.huihui.example.Test { 

  <init>; #匹配所有构造器
  <fields>;#匹配所有域
  <methods>;#匹配所有方法}
  
  public void test(java.lang.String); # 特定方法
  public <methods>;#保持该类下所有的共有方法不被混淆
  public *;#保持该类下所有的共有内容不被混淆
  private <methods>;#保持该类下所有的私有方法不被混淆
  private *;#保持该类下所有的私有内容不被混淆
  public <init>(java.lang.String);#保持该类的String类型的构造方法
}

-keep class name.huihui.example.Test$* {
      *;
}

Thanks

上一篇下一篇

猜你喜欢

热点阅读