Android 代码混淆,混淆打包

时间:2023-02-21 21:20:18

分为三步:

0:开通混淆,

1:第二步是设置混淆

2:最重要的是设置哪些不混淆

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



0:第一步是开通混淆

这里在build.gradle里面设置:minifyEnabled 为true

buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
如果有考虑多渠道那么:如下的flavor里面设置

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

productFlavors {
flavor1 {
}
flavor2 {
proguardFile 'other-rules.pro'
}
}



1:第二步是设置混淆

该文件就是上面的proguard-rules.pro,在项目里面应该可以找到的,如果没有找到,可以手动的创建这个文件

Android 代码混淆,混淆打包

首先要了解的是我们混淆的步骤是这样的:

首先是shrink 压缩,然后是optimize优化,然后是obfuscate 混淆,然后是preverify 审核器

shrink 压缩 查看哪些类或者类的组件(例如变量吧)没有被使用,可以将他们抛弃掉
In the shrinking step, ProGuard starts from these seeds and recursively determines which classes and class members are used. All other classes and class members are discarded.
optimize优化 进一步的优化,在优化里面,将一些不是其二点的类和方法可以将他们命名为私有的静态的或者final的,没有使用的参数可以被删除,其他的方法可以弄成一行显示
In the optimization step, ProGuard further optimizes the code. Among other optimizations, classes and methods that are not entry points can be made private, static, or final, unused parameters can be removed, and some methods may be inlined.
obfuscate 混淆 In the obfuscation step, ProGuard renames classes and class members that are not entry points. In this entire process, keeping the entry points ensures that they can still be accessed by their original names.
将不是切入点的类和方法的名字重新命名,在这个处理阶段,保证切入点的类和方法可以使用原来的名字访问
preverify 审核器预校验 它是唯一一步不用去关心切入点的步骤
The preverification step is the only step that doesn't have to know the entry points.

Android 代码混淆,混淆打包

################### -0- Input/Output Options #######################

#不去忽略非公共的库类
#proguard 的4.5版本以后,这个属性是默认的,我们的版本是5.2.1,可以不写
-dontskipnonpubliclibraryclasses


#################### -2- optimization Options ##########################

#优化的轮次(pass)
-optimizationpasses 5


#优化 不优化输入的类文件
#注意这里只是不优化输入的类文件,后面的-optimizations 还是可以起作用的,-optimizationss是更细节的
-dontoptimize

# 应该是优化时候的过滤,只在优化的阶段时候有用,而不是混淆的阶段。
# 过滤相关的在这里http://proguard.sourceforge.net/manual/optimizations.html
# For example, "code/simplification/variable,code/simplification/arithmetic" only performs the two specified peephole optimizations.
# For example, "!method/propagation/*" performs all optimizations, except the ones that propagate values between methods.
# For example, "!code/simplification/advanced,code/simplification/*" only performs all peephole optimizations.
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*


#################### -3- Obfuscation Options ##########################

#包明不混合大小写
#混淆后的包明不混合大小写,只有小写
-dontusemixedcaseclassnames

#保护注解
#-keepattributes [attribute_filter]
# Specifies any optional attributes to be preserved. The attributes can be specified with one or more -keepattributes directives. The optional filter is a comma-separated list of attribute names that Java virtual machines and ProGuard support. Attribute names can contain ?, *, and ** wildcards, and they can be preceded by the ! negator. For example, you should at least keep the Exceptions, InnerClasses, and Signature attributes when processing a library. You should also keep the SourceFile and LineNumberTable attributes for producing useful obfuscated stack traces. Finally, you may want to keep annotations if your code depends on them. Only applicable when obfuscating.
-keepattributes *Annotation*

#对于一个类来说,属性attribute 就是例如bytecode,文件名,行号等
#Class files essentially define classes, their fields, and their methods. A lot of essential and non-essential data are attached to these classes, fields, and methods as attributes. For instance, attributes can contain bytecode, source file names, line number tables, etc.
#2016年08月09日10:14:09百度查到可以用这个配置保留错误的行号,有待测试,如果可以能方便查错
-keepattributes SourceFile,LineNumberTable

################### -4- preverify Options #######################
#预校验
#取消预校验
-dontpreverify

################### -5- General Options #######################

#混淆时是否记录日志
-verbose

#忽略警告
-ignorewarnings


#####################记录生成的日志数据,gradle build时在本项目根目录输出################
#输出项目目录\model的名称\build\outputs\mapping\release
#例如我的这个路径就是C:\AndroidStudioProjects\AndroidStudioProjects\MixDemo\app\build\outputs\mapping\release

#apk 包内所有 class 的内部结构
#dump 是转储的意思
#General Options
-dump class_files.txt

#未混淆的类和成员
#Input/Output Options
-printseeds seeds.txt

#列出从 apk 中删除的代码
#Shrink Options
-printusage unused.txt

#混淆前后的映射
#Obfuscation Options
#-printmapping mapping.txt

#重用同一个mapping
#Obfuscation Options
#-applymapping /Users/drome/Developer/mi-cashier-android/cashierbeta/build/outputs/mapping/release/mapping.txt
-applymapping C:\500mi\Published Builds\mapping\mapping.txt
#####################记录生成的日志数据,gradle build时 在本项目根目录输出-end################

2:最重要的是设置哪些不混淆

################### 保持哪些类不被混淆#################
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
#如果有引用v4包可以添加下面这行
-keep public class * extends android.support.v4.app.Fragment


####################以libaray的形式引用的框架,如果不想混淆 keep 掉##############
-keep class com.nostra13.universalimageloader.** { *; }
-keep class com.handmark.pulltorefresh.library.**{*;}
-keep class com.drome.lib_android_usb_serial.usbserial.**{*;}

####################友盟##########################
-keep class com.umeng.**{*;}
#友盟消息推送混淆配置
-keep class com.umeng.message.* {
public <fields>;
public <methods>;
}

-keep class com.umeng.message.protobuffer.* {
public <fields>;
public <methods>;
}

-keep class com.squareup.wire.* {
public <fields>;
public <methods>;
}

-keep class com.umeng.message.local.* {
public <fields>;
public <methods>;
}
-keep class org.android.agoo.impl.*{
public <fields>;
public <methods>;
}

################andfix混淆配置###############################
-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
native <methods>;
}
-keep class com.alipay.euler.andfix.** { *; }


######################gson #############################
#-libraryjars libs/gson-2.2.2.jar
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }


##################### webview + js######################
-keepattributes *JavascriptInterface*
# keep 使用 webview 的类
-keepclassmembers class com.veidy.activity.WebViewActivity {
public *;
}
# keep 使用 webview 的类的所有的内部类
-keepclassmembers class com.veidy.activity.WebViewActivity$*{
*;
}


###################阿里OSSClient对象存储服务#################
-keep class com.alibaba.sdk.android.oss.** { *; }
-dontwarn okio.**
-dontwarn org.apache.commons.codec.binary.**


###################信鸽推送#################################
-keep class com.tencent.android.tpush.** {* ;}
-keep class com.tencent.mid.** {* ;}

############<span></span>混淆保护自己项目的部分代码以及引用的第三方jar包library-end##################

-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}

#保持 native 方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}

#保持自定义控件类不被混淆
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

#保持自定义控件类不被混淆
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
#保持自定义控件类不被混淆
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

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

#保持 Serializable 不被混淆
-keepnames class * implements java.io.Serializable

#保持 Serializable 不被混淆并且enum 类也不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

#保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可
#-keepclassmembers enum * {
# public static **[] values();
# public static ** valueOf(java.lang.String);
#}

-keepclassmembers class * {
public void *ButtonClicked(android.view.View);
}

#不混淆资源类
-keepclassmembers class **.R$* {
public static <fields>;
}

#####################Others###########################

-dontwarn com.xiaomi.**

-dontwarn com.ut.mini.**

-keep class org.android.agoo.service.* {*;}

-keep class org.android.spdy.**{*;}

-keep class com.wbm.app.business.model.**{*;}
-keep class com.wbm.app.business.model.Wholesale.SimulateCreateCashierTrade.**{*;}
-keep class com.wbm.app.utils.**{*;}

-keep class org.litepal.**{*;}

-keep class com.taobao.**{*;}
#应该是Fresco
-keep class com.facebook.** {* ;}

#如果引用了v4或者v7包
-dontwarn android.support.**




参考:

http://proguard.sourceforge.net/

https://segmentfault.com/a/1190000004461614


官方给出的Android的项目的混淆的example:http://proguard.sourceforge.net/manual/examples.html#androidactivity

-injars      bin/classes
-injars libs
-outjars bin/classes-processed.jar
-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar

-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.content.Context {
public void *(android.view.View);
public void *(android.view.MenuItem);
}

-keepclassmembers class * implements android.os.Parcelable {
static ** CREATOR;
}

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

-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}


通配符匹配规则

通配符 规则
匹配单个字符
* 匹配类名中的任何部分,但不包含额外的包名
** 匹配类名中的任何部分,并且可以包含额外的包名
% 匹配任何基础类型的类型名
* 匹配任意类型名 ,包含基础类型/非基础类型
... 匹配任意数量、任意类型的参数
<init> 匹配任何构造器
<ifield> 匹配任何字段名
<imethod> 匹配任何方法
*(当用在类内部时) 匹配任何字段和方法
$ 指内部类

更详细的语法请戳:http://proguard.sourceforge.ne