android studio混淆打包 总结 站在别人的肩膀上--看的更远

======================================步骤一======================

Gradle

1.主要看buildTypes里面的内容

   

import com.android.builder.core.BuilderConstants
import com.android.builder.model.ClassField

apply plugin: 'com.android.application'

repositories {
    maven {
        url 'https://oss.sonatype.org/content/repositories/snapshots'
    }
}
android {
    signingConfigs {
        release {
            keyAlias 'dongxiang'
            keyPassword 'dongxiang'
            storeFile file('C:/Users/Administrator/Desktop/As_基础/keystore_jc.jks')
            storePassword 'dongxiang'
        }
    }
    compileSdkVersion 26//只是在编译的时候使用,打包的时候使用:强烈推荐总是使用最新的 SDK 进行编译
    buildToolsVersion "26.0.1"
    useLibrary 'org.apache.http.legacy'
    defaultConfig {
        applicationId "com.dongxaing.dx"
        minSdkVersion 16
        targetSdkVersion 22//这个版本号不需要和上面的compileSdkVersion26 一样
        versionCode 37
        versionName "1.02.37"
        multiDexEnabled true//生成多个dex文件---3-1
        /*版本名字,三位数; 27-27
			同时也要更新版本号*/
//        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
//    allprojects {
//       gradle.projectsEvaluated {//过时方法,检测
//            tasks.withType(JavaCompile) {
//                options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" }
//             }
//    }
    buildTypes {
        debug {
            // 显示Log
            buildConfigField "boolean", "LOG_DEBUG", "true"
            versionNameSuffix "-debug"
//            minifyEnabled false
//            zipAlignEnabled false
//            shrinkResources false

            //Zipalign优化
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            //混淆--
            minifyEnabled true
            //前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件
//            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//默认不优化
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'//optimize 默认优化就是这两个文件的区别
//            //签名
//            signingConfig signingConfigs.release
        }
        release {
            // 不显示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            //Zipalign优化
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            //混淆--
            minifyEnabled true
            //前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件
//            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//默认不优化
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'//optimize 默认优化就是这两个文件的区别
//            //签名
//            signingConfig signingConfigs.release
        }
    }
    //设置生成的apk命名:DX_v1.02.37_DemoDX1_debug_2017-10-26.apk
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                // 输出apk名称为DX_v1.02.37_DemoDX1_debug_2017-10-26.apk
//                def fileName = "DX_v${defaultConfig.versionName}_${variant.productFlavors[0].name}_release_${releaseTime()}.apk";
                def fileName
                if (variant.buildType.name == ('release')) {
                    fileName = "DX_v${defaultConfig.versionName}_${getProductFlavors(variant)}_release_${releaseTime()}.apk";
                } else if (variant.buildType.name == ('debug')) {
                    fileName = "DX_v${defaultConfig.versionName}_${getProductFlavors(variant)}_debug_${releaseTime()}.apk";
                }
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }
    //配置多版本的apk,
    productFlavors {
        base {
            applicationId "com.dongxiang.dx"
            resValue("string", "strKey", "DemoDX1")
        }
        DX2 {
            applicationId "com.dongxiang.dx2"
            resValue("string", "strKey", "DemoDX2")
        }
    }
    aaptOptions {
        cruncherEnabled = false
    }
    lintOptions {
        checkReleaseBuilds false
        //执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉
        abortOnError false
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}
def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
/**
 * 获取多版本的 是哪个版本的名字
 * @param variant Closure
 * @return
 */
def getProductFlavors(def variant){
    ClassField alreadyPresent = variant.mergedFlavor.resValues.get("strKey");//这个是获取strKey值
    def flavorNameVar= variant.flavorName;
    if (alreadyPresent != null) {
//        String flavorName =  variant.mergedFlavor.name;//这个获取的是类名:base或者DX2;
//        if (BuilderConstants.MAIN.equals(flavorName)) {
//            logger.info(
//                    "DefaultConfig: resValue '{}'",
//                    variant.mergedFlavor.name, alreadyPresent.value);
//        } else {
//            logger.info(
//                    "ProductFlavor({}): resValue '{}'",
//                    flavorName, variant.mergedFlavor.name, alreadyPresent.value, " 11111 ");
//        }
        flavorNameVar=alreadyPresent.value;
    }
    return flavorNameVar;
}

afterEvaluate {//生成多个dex文件---3-2
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = ['--multi-dex']
        } else {
            dx.additionalParameters += '--multi-dex'
        }
    }
}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    //生成多个dex文件---3-3;最后将BaseApplication集成注释1
    compile 'com.android.support:multidex:1.0.0'
    testCompile 'junit:junit:4.12'
    //    数据库加密3-1;3-2 是将android.database.sqlite.*包换成:net.sqlcipher.*包:;3-3 别忘记调用SQLiteDatabase.loadLibs(context);
    compile files('libs/commons-codec.jar')
    compile files('libs/guava-r09.jar')
    compile files('libs/sqlcipher.jar')
}

             

注释1:BaseApplication重写Application的方法:

有关分包dex详见:AndroidStudio中的 multidex 的 Dex分包步骤

@Override
protected void attachBaseContext(Context base) {
  super.attachBaseContext(base);
  MultiDex.install(this);
}

======================================步骤二======================

混淆文件:

1.文件位置

2.文件内容通用

   

# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\AndroidSoft\Eclipses_64\android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

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

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

#代码混淆压缩比,在0~7之间,默认为5,一般不做修改
-optimizationpasses 5

#使代码不被压缩优化,使得注解代码不被优化掉(优化掉了,点击事件就不能用了,如xutils的点击事件的代码就被优化掉了)
-dontshrink

#混合时不使用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames

#指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses

# 指定不去忽略非公共库的类成员
-dontskipnonpubliclibraryclassmembers

# #不优化输入的类文件/不要优化;会导致log依旧能输出   -dontoptimize

 #不做预校验,preverify是proguard的四个步骤之一,
 #Android不需要preverify,去掉这一步能够加快混淆速度。
-dontpreverify

#避免混淆泛型 如果混淆报错建议关掉
-keepattributes Signature

# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable

##记录生成的日志数据,gradle build时在本项目根目录输出-start##
 #混淆时是否记录日志
-verbose
#忽略警告
-ignorewarning
#apk 包内所有 class 的内部结构
-dump proguard/class_files.txt
#未混淆的类和成员
-printseeds proguard/seeds.txt
#列出从 apk 中删除的代码
-printusage proguard/unused.txt
#混淆前后的映射
-printmapping proguard/mapping.txt
########记录生成的日志数据,gradle build时 在本项目根目录输出-end######

 # 指定混淆是采用的算法,后面的参数是一个过滤器
 # 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses

#############################################
#
# Android开发中一些需要保留的公共部分
#
#############################################
# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
# 因为这些子类都有可能被外部调用
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep class com.redoor.rcs.RCSApplication{*;}
-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 * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
# 保留support下的所有类及其内部类: 包含了 multidex
-keep class android.support.** {*;}

#如果有引用v4包可以添加下面这行
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**

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

#这个主要是在layout 中写的onclick方法android:οnclick="onClick",不进行混淆
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}


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



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

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

#保持自定义控件类不被混淆
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

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

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

# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
    void *(**On*Event);
    void *(**On*Listener);
}

# webView处理,项目中没有使用到webView忽略即可
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
    public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
    public void *(android.webkit.webView, jav.lang.String);
}

#保持枚举 enum 类不被混淆
-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>;
}

#移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,
#这里可以作为禁止log打印的功能使用,
#另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
-assumenosideeffects class android.util.Log {
    public static *** v(...);
    public static *** i(...);
    public static *** d(...);
    public static *** w(...);
    public static *** e(...);
}
-assumenosideeffects class java.io.PrintStream {
     public *** println(...);
     public *** print(...);
}



3.常用第三方模块的混淆选项:

       

#######################     常用第三方模块的混淆选项         ###################################
#mob
-keep class android.net.http.SslError
-keep class android.webkit.**{*;}
-keep class cn.sharesdk.**{*;}
-keep class com.sina.**{*;}
-keep class m.framework.**{*;}
-keep class **.R$* {*;}
-keep class **.R{*;}
-dontwarn cn.sharesdk.**
-dontwarn **.R$*

######引用的其他Module可以直接在app的这个混淆文件里配置

#####混淆保护自己项目的部分代码以及引用的第三方jar包library#######
#一、如果在当前的application module或者依赖的library module中使用了第三方的库,
#   并不需要显式添加规则  -libraryjars xxx
#   添加了反而有可能在打包的时候遭遇同一个jar多次被指定的错误,
#   一般只需要添加忽略警告和保持某些class不被混淆的声明。

#二、以libaray的形式引用了开源项目,如果不想混淆,那就keep掉;在引入的module的build.gradle中设置minifyEnabled=false
#xUtils
#-libraryjars libs/xutils-2.6.14.jar
-dontwarn com.lidroid.**
-keep class com.lidroid.** { *; }

# Bugly
-dontwarn com.tencent.bugly.**
-keep class com.tencent.bugly.** {*;}

# ButterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

# EventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Facebook
-keep class com.facebook.** {*;}
-keep interface com.facebook.** {*;}
-keep enum com.facebook.** {*;}

# FastJson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keepattributes Signature
-keepattributes *Annotation*

# Fresco
-keep class com.facebook.fresco.** {*;}
-keep interface com.facebook.fresco.** {*;}
-keep enum com.facebook.fresco.** {*;}

# 高德相关依赖
# 集合包:3D地图3.3.2 导航1.8.0 定位2.5.0
-dontwarn com.amap.api.**
-dontwarn com.autonavi.**
-keep class com.amap.api.**{*;}
-keep class com.autonavi.**{*;}
# 地图服务
-dontwarn com.amap.api.services.**
-keep class com.map.api.services.** {*;}
# 3D地图
-dontwarn com.amap.api.mapcore.**
-dontwarn com.amap.api.maps.**
-dontwarn com.autonavi.amap.mapcore.**
-keep class com.amap.api.mapcore.**{*;}
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.amap.mapcore.**{*;}
# 定位
-dontwarn com.amap.api.location.**
-dontwarn com.aps.**
-keep class com.amap.api.location.**{*;}
-keep class com.aps.**{*;}
# 导航
-dontwarn com.amap.api.navi.**
-dontwarn com.autonavi.**
-keep class com.amap.api.navi.** {*;}
-keep class com.autonavi.** {*;}

# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

# Gson
#如果用用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
# 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。# 将下面替换成自己的实体类
-keep class com.example.bean.** { *; }
# Jackson-dontwarn org.codehaus.jackson.**
-dontwarn com.fasterxml.jackson.databind.**
-keep class org.codehaus.jackson.** { *;}
-keep class com.fasterxml.jackson.** { *; }
# 极光推送
-dontoptimize
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
# OkHttp3
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
# Okio-dontwarn com.squareup.**
-dontwarn okio.**
-keep public class org.codehaus.* { *; }
-keep public class java.nio.* { *; }
# OrmLite
-keepattributes *DatabaseField*
-keepattributes *DatabaseTable*
-keepattributes *SerializedName*
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
# Realm
-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class * { *; }
-dontwarn javax.**
-dontwarn io.realm.**# Retrofit-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
# Retrolambda
-dontwarn java.lang.invoke.*
# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
# 微信支付
-dontwarn com.tencent.mm.**
-dontwarn com.tencent.wxop.stat.**
-keep class com.tencent.mm.** {*;}
-keep class com.tencent.wxop.stat.**{*;}
# 信鸽
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep class com.tencent.android.tpush.**  {* ;}
-keep class com.tencent.mid.**  {* ;}
-keepattributes *Annotation*
# 新浪微博
-keep class com.sina.weibo.sdk.* { *; }
-keep class android.support.v4.* { *; }
-keep class com.tencent.* { *; }
-keep class com.baidu.* { *; }
-keep class lombok.ast.ecj.* { *; }
-dontwarn android.support.v4.**
-dontwarn com.tencent.**
-dontwarn com.baidu.**
# 讯飞语音
-dontwarn com.iflytek.**
-keep class com.iflytek.** {*;}
# 银联
-dontwarn com.unionpay.**
-keep class com.unionpay.** { *; }
# 友盟统计分析
-keepclassmembers class * { public <init>(org.json.JSONObject); }
-keepclassmembers enum com.umeng.analytics.** {    
	public static **[] values();
    public static ** valueOf(java.lang.String);
}
# 友盟自动更新
-keepclassmembers class * { 
	public <init>(org.json.JSONObject);	
}
-keep public class cn.irains.parking.cloud.pub.R$*{ public static final int *; }
-keep public class * extends com.umeng.**-keep class com.umeng.** { *; }
# 支付宝钱包
-dontwarn com.alipay.**
-dontwarn HttpUtils.HttpFetcher
-dontwarn com.ta.utdid2.**
-dontwarn com.ut.device.**
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
-keep class com.alipay.mobilesecuritysdk.*
-keep class com.ut.**
#保护含有main方法的类以及这个类的main方法
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}

       



===============================学习  三 @Keep注释类==========================

三、学习@Keep

  1. @Keep
    在使用@Keep注解之前我们需要先导入
    compile 'com.android.support:support-annotations:25.1.1'类库
    使用方法非常简单,可以注解在类,方法和变量,总结起来就是一句话哪里不想被混淆就注解哪里。

        2. Test类,内容如下:

@Keep
public class Test {
    int age = 20;
    @Keep
    protected String sex = "m";
    @Keep
    public String name = "CodingMaster";

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    private void cry(){

    }
}
混淆结果为:




四、混淆语法

1.例如一个包下的的两个类:一个bean ,和一个接口

package com.ticktick.example;

public interface TestInterface {
    public void test();
}

public class Test {

    private String mTestString;
    private final int mMinValue;
    private final int mMaxValue;

    public Test( int min, int max){
        mMinValue = min;
        mMaxValue = max;
    }

    public int getMinValue() {
        return mMinValue;
    }

    public int getMaxValue() {
        return mMaxValue;
    }

    public void setTestString(String testStr ) {
        mTestString = testStr;
    }
}


1.不混淆某个类的构造函数

-keepcalssmembers clsss com.ticktick.example.Text{
    public <init>(int,int)
}

2.不混淆某个包下所有的类或者指定的类

  注:如果希望不混淆某个接口,则把下面命令的class替换为interface即可.

#不混淆这个包下的所有的类
-keep class com.ticktick.example.**{*;}

#不混淆com.ticktick.example.Text类
-keep class com.ticktick.example.Text{*;}


3.不混淆某个类的特定的函数

#不混淆com.ticktick.example.Test类中的setTestString函数
-keepclassmembers class com.ticktick.example.Test{
    public void setTestString(java.lang.String);
}


4.不混淆某个类的子类,某个接口的实现

#不混淆com.ticktick.example.Test的子类
-keep public class * extend com.ticktick.example.Test

#不混淆com.ticktick.example.TestInterface的实现
-keep class * implements com.ticktick.example.TestInterface{
    public static final com.ticktick.example.TestInterface$Creator *;
}


5.注意第三方依赖包

#添加android-support-v4.jar依赖包
-libraryjars libs/android-support-v4.jar
-dontwarn android.support.v4.**{*;}
-keep class android.support.v4.**{*;}
-keep interface android.support.v4.**{*;}

注意:

添加dontwarn,因为默认情况下proguard会检查每一个引用是否正确,

但是第三方库里往往有些不会用到的类,没有正确引用,所有如果不配置的话,系统会报错.

五 Progroud的语法:

1.   -berbose声明在处理过程中输出更多信息,添加这项配置之后,如果处理过程中出现异常,会输出整个StackTrace而不是一条简单的异常说明.

2.   -dontwarn {class_filter}声明不输出那些未找到的引用和一些错误,继续混淆.配置中的class_filter是一串正则表达式.

3 ? ----------- 匹配单个字符

4 * ----------- 匹配类名中的任何部分,但不包含额外的包名

5 ** ----------- 匹配类名中的任何部分,并且可以包含额外的包名

6 % ----------- 匹配任何基础类型的类型名

7 ... ---------- 匹配认识数量 任意类型的参数

8 <init> ------- 匹配任何构造器

9 <ifield> ----- 匹配任何字段名

10 * ----------- (当用在类内部时) 匹配任何字段和方法

11 $ ----------- 指内部类


12  keep 保留配置项:



 
 

-keep {Modifier(修饰符)}{class_specification(类规范)} 保护指定的类和类的成员

#例如对一个可执行jar包来说,需要保护main的入口类,对一个类库来说需要保护它的所有public元素
-keep public class MyMain{
    public static void main(java.lang.String[]);
}


  
  
-keepclassmembers {Modifier}{class_specification}  保护指定类的成员,如果此类也受到保护他们会保护的更好
#例如指定继承了Serizalizable的类的如下成员不被混淆,成员属性和方法,非私有的属性非私有的方法.
-keepclassmembers class * implements java.io.Serializable{
    static final long seriaVersionUID;
    !private <fields>;
    !private <methods>;
    private void writeObject(java.io.ObjectOuputStream);
}


   
   
     
     
-keepclasseswithmembers{Modifier}{class_specification} 保护指定成员的类,根据成员确定一些将要被保护的类
#保护含有main方法的类以及这个类的main方法
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}


    
    
-keepnames {Modifier}{class_specification}  这个是-keep,allowshrinking {Modifier}{class_specification}的简写.意思是说允许压缩操作,如果在压缩过程中没有被删除,那么类名和该类中的成员的名字会被保护
-keepclassmembernames {Modifier}{class_specification}如果在压缩过程中没有被删除在保护这个类中的成员
-keepclasseswithmembers {Modifier}{class_specification}如果在压缩过程中该类没有被删除,同样如果该类中有某个成员字段或者方法,那么保护这个类和这个方法.
-printseeds{filename}将keep的成员输出到文件或者打印到标准输出流.

13 shrinker配置  代码压缩配置

-dontshrink 声明不压缩文件.默认情况下,除了-keep相关指定的类,其它所有的没有被引用到的类都会被删除,每次优化(optimizate)操作之后也会执行一次压缩操作,因为每次优化操作可能删除一部分不在需要的类.
-printusage{filename} 将被删除的元素输出到文件,或者打印到保准输出流
-whyareyoukeeping {class_specification} 打印为什么吗一个类或类的成员被保护,这对检查一个输出文件中的类的结果有帮助.

14  optimizate配置 代码优化配置

-dontoptimize 声明不优化的文件.默认情况下,优化选项是开启的,并且所有的优化都是在字节码层进行的.
-optimizations 更加细粒度的声明优化开启或者关闭.
-optimizationpasses n 指定执行几次优化,默认情况只执行一次优化,执行多次优化可以提高优化的效果.但是如果执行一次优化之后没有效果,就会停止优化,剩下的设置次数不在执行.

15  obfuscate配置 混淆配置

-dontobfuscate 声明不混淆 默认情况下,混淆是开启的.除了keep配置中的类其它的类或者类的成员混淆后会改成随机简短的名字
printmapping{filename} 指定输出新旧元素名的对照表的文件,可以通过在build.gradle中的配置,进行自动保存.这个在异常追踪的时候非常有用可以参考这个粗暴接触混淆
-applymapping {filename}指定重用一个已经写好的map文件作为新旧元素名的映射.元素名已经存在的就按照该文件中的配置进行,对于没存在的就重新赋一个新的名字
obfuscationdictionary {filename}指定一个文本文件用来生成混淆后的名字.默认情况下混淆后的名字一般为a,b,c.通过这个选项配置的字典文件,可以使用一些非英文字符做为类名,成员名,方法名.需要注意的是添加了字典并不会显著提高混淆的效果,只不过是更不利与人类的阅读。正常的编译器会自动处理他们,并且输出出来的jar包也可以轻易的换个字典再重新混淆一次。最有用的做法一般是选择已经在类文件中存在的字符串做字典,这样可以稍微压缩包的体积。
     
     
#查找字典文件的格式:一行一个单词,空行忽略,重复忽略
# 这里巧妙地使用java中的关键字作字典,混淆之后的代码更加不利于阅读
#
# This obfuscation dictionary contains reserved Java keywords. They can't
# be used in Java source files, but they can be used in compiled class files.
# Note that this hardly improves the obfuscation. Decent decompilers can
# automatically replace reserved keywords, and the effect can fairly simply be
# undone by obfuscating again with simpler names.
# Usage:
#     java -jar proguard.jar ..... -obfuscationdictionary keywords.txt
#
do
if
for
int
new
try
byte
case
char
else
goto
long
this
void
break
catch
class
const
final
float
short
super
throw
while
double
import
native
public
return
static
switch
throws
boolean
default
extends
finally
package
private
abstract
continue
strictfp
volatile
interface
protected
transient
implements
instanceof
synchronized


      
      
-classobfuscationdictionary {filename}指定一个混淆类名的字典,字典格式与-obfuscationdictionary相同
-packageobfuscationdictionary {filename}指定一个混淆包名的字段
-oberloadaggressively 混淆的时候大量使用重载,多个方法名使用同一个混淆名,但是它们的方法签名不同,这可以使包的体积减小一部分也可以加大理解难度.
不过这个配置有一定的限制 oberloadaggressively 

Sun的JDK1.2上会报异常
Sun JRE 1.4上重载一些方法之后会导致序列化失败
Sun JRE 1.5上pack200 tool重载一些类之后会报错
java.lang.reflect.Proxy类不能处理重载的方法


       
       
-useuniqueclassmembernames 指定相同的混淆名对应相同的方法名,不同的混淆名对应不同的方法名.如果不设置这个选项,同一个类中将会有很多方法映射到相同的方法名.这项配置会稍微增加输出文件中的代码,但是它能够保证 保存下来的mapping文件能够在随后的增量混淆中继续被遵守,避免重新命名.比如说两个接口拥有同名的方法和相同的签名,如果没有这个配置,在第一次打包混淆之后它们两个方法可能会被赋予不同的混淆名.如果下一次添加代码有一个类同时实现了这两个接口,那么混淆的时候必然会将两个混淆后的方法名统一起来.这样就必须要改混淆文件其中一处的配置,也就不能保证前后两次混淆的mapping文件一致了(如果想用一份mappping文件迭代更新的话,这项配置比较有用).
-dontusemixedcaseclassnames 指定在混淆的时候不使用大小写混用的类名.默认情况下混淆后的类名可能同时包含大写字母和小写字母.这样的jar并没有什么问题,只有在大小写不敏感的window系统上解压时,才会涉及问题.因为大小写不区分,可能会导致部分文件在解压的时候相互覆盖.
-keeppackagenames{package_filter} 声明不混淆指定的包名,配置的过滤器是逗号隔开的一组包名.包名可以包含? *通配符,并且可以在前面加!否定符
-flatternpackagenames{packagename} 所有重命名的包都重新打包,并把所有的类移动到packagename包下面.如果没有指定packagename或者packagename为”“,那么所有的类都会被移动到根目录下.
-repackageclasses{package_name} 所有重新命名类都重新打包,并把它们移动到指定的packagename目录下.这项配置会覆盖-flatternpackagehierarchy的配置.他可以使代码体积更小,并且更加难以理解.
需要注意的是如果需要从目录中读取资源文件,移动包的位置可能会导致异常.如果出现这个问题,就不要用这个配置了.-repackageclasses{package_name} 

-keepattributes{attribute_filter} 指定受保护的属性.可以有一个或者多个该配置项,每个配置后面跟随的是java虚拟机和proguard支持的attribute(具体支持的属性先看这里),两个属性之间用逗号分隔.属性名可以使用通配符,或者! 将某个属性排除在外.当混淆一个类库的时候至少要保持InnerClasses,Exceptions,Signature属性.为了跟踪异常信息,需要把SourceFile,LineNumberTable两个属性保留.如果代码中有用到注解,需要Annotion属性.
#可以分开写
-keepattributes SourceFile, LineNumberTable
-keepattributes *Annotation*
-keepattributes EnclosingMethod
# 可以直接写在一行
-keepattributes Exceptions, InnerClasses, Signature, Deprecated,
                SourceFile, LineNumberTable, *Annotation*, EnclosingMethod


        
        

-keepparameternames 指定被保护的方法的参数类型和参数名不被混淆.这项配置在混淆一些类库的时候特别有用,因为根据IDE提示的参数名和参数类型,开发者可以根据语意获得一些信息.
-adaptclassstrings{classfilter}指定字符串常量如果与类名相同,也需要被混淆.如果没有加classfilter,所有的符合要求的字符串常量都会被混淆;如果带classfilter,只有在匹配的类中的字符串常量才会受此影响.例如在你的代码中有大量的类名对应的字符串的hard-code,并且不想保留它们的本名,那就可以利用哦这项配置来完成.
-adaptresourcefileanmes{file_filter} 如果资源文件与某类同名,那么混淆后资源文件被命名为与之对应的类的混淆名.不加file_filter的情况下,所有资源文件都受此影响,加了file_filter的情况只有匹配的类才受此类的影响.
-adaptresourcefilecontents{file_filter}指定资源文件的中的类名随混淆后的名字更新.根据被混淆的名字的前后映射关系,更新文件中对应的包名和类名.









         
         









         
         









         
         









         
         





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值