以前一直说混淆、混淆。。。一直没有好好弄一次,经常弄个半成品,这次来个完全实例理解了
并注意,混淆打包后的apk文件大小会比不使用混淆要小。

首先理解下混淆语法

-libraryjars class_path 应用的依赖包,如android-support-v4  -keep [,modifier,...] class_specification 不混淆某些类  -keepclassmembers [,modifier,...] class_specification 不混淆类的成员  -keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员  -keepnames class_specification 不混淆类及其成员名  -keepclassmembernames class_specification 不混淆类的成员名  -keepclasseswithmembernames class_specification 不混淆类及其成员名  -assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等  -dontwarn [class_filter] 不提示warnning  

其中app是应用主模块,引用剩余的module,被引用module的build.gradle中都使用默认的设置不启用混淆:

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

在主module的build.gradle:

apply plugin: 'com.android.application'apply plugin: 'com.neenbedankt.android-apt'def releaseTime() {    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))}repositories {    maven {        url 'https://oss.sonatype.org/content/repositories/snapshots'    }}android {    compileSdkVersion 25    buildToolsVersion '25.0.0'    defaultConfig {        applicationId "com.*****.****" //自己的applicationId        minSdkVersion 14        targetSdkVersion 25        versionCode 1        versionName "1.0"    }    //执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。    lintOptions {        abortOnError false    }    //签名    signingConfigs {        debug {        }        release {// 自己的签名文件            storeFile file("doc/****.jks")             storePassword "******"            keyAlias "******"            keyPassword "******"        }    }    buildTypes {        debug {            // 显示Log            buildConfigField "boolean", "LOG_DEBUG", "true"            versionNameSuffix "-debug"            minifyEnabled false            zipAlignEnabled false            shrinkResources false            signingConfig signingConfigs.debug        }        release {            // 不显示Log            buildConfigField "boolean", "LOG_DEBUG", "false"            //混淆            minifyEnabled true            //Zipalign优化            zipAlignEnabled true            // 移除无用的resource文件            shrinkResources true            //前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            //签名            signingConfig signingConfigs.release            applicationVariants.all { variant ->                variant.outputs.each { output ->                    def outputFile = output.outputFile                    if (outputFile != null && outputFile.name.endsWith('.apk')) {                        // 输出apk名称为app_v1.0_2015-xx-xx_xxxx.apk                        //def fileName = "app_v${defaultConfig.versionName}_${releaseTime()}.apk"                        def fileName = "app_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"                        output.outputFile = new File(outputFile.parent, fileName)                    }                }            }        }    }    //渠道Flavors,配置不同风格的app,友盟渠道统计时用到    productFlavors {        "offical" {}        "360" {}        yingyongbao {}        wandoujia {}        baidu {}        "91" {}    }}repositories {    maven {        url "https://repo.eclipse.org/content/repositories/paho-releases/"    }    maven { url "https://jitpack.io" }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    compile 'com.android.support:design:23.4.0'    compile 'com.android.support:support-v4:23.4.0'    compile 'com.android.support:appcompat-v7:23.4.0'    compile 'com.android.support:appcompat-v7:23.4.0'    compile 'com.android.support:cardview-v7:23.4.0'    compile 'com.android.support:recyclerview-v7:23.4.0'    //1 achartengine图形    compile files('libs/achartengine-1.1.0.jar')    //2 高德地图    compile files('libs/AMap2DMap_2.9.1.jar')    //3 butterknife注解    apt 'com.jakewharton:butterknife-compiler:8.1.0'    compile 'com.jakewharton:butterknife:8.1.0'    //4 smack    compile 'org.igniterealtime.smack:smack-android-extensions:4.1.8'    compile 'org.igniterealtime.smack:smack-tcp:4.1.8'    //5 eventbus    compile 'org.greenrobot:eventbus:3.0.0'    //6 greendao    compile 'org.greenrobot:greendao:3.1.1'    //7 FlycoTabLayout_Lib    compile 'com.flyco.tablayout:FlycoTabLayout_Lib:[email protected]'    //8 mqttv3    compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'    //9 mqtt service    compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'    //10 gson    compile 'com.google.code.gson:gson:2.7'    //11 MPAndroidChart    compile 'com.github.PhilJay:MPAndroidChart:v3.0.0-beta1'    //12 logger    compile 'com.orhanobut:logger:1.15'    //13 picasso    compile 'com.squareup.picasso:picasso:2.5.2'    //14 okhttp3    compile 'com.squareup.okhttp3:okhttp:3.4.1'    //15 retrofit2.0    compile 'com.squareup.retrofit2:retrofit:2.1.0'    compile 'com.squareup.retrofit2:converter-gson:2.1.0'    compile 'com.squareup.retrofit2:converter-scalars:2.1.0'    //16 zxing    compile 'com.google.zxing:core:3.3.0'}

proguard-rules.pro文件中则定义了项目的混淆选项,定义如下:

# Add project specific ProGuard rules here.# By default, the flags in this file are appended to flags specified# in D:\COMPETITION\Android Studio\Android Studio 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 *;}#指定代码的压缩级别-optimizationpasses 5#包明不混合大小写-dontusemixedcaseclassnames#不去忽略非公共的库类-dontskipnonpubliclibraryclasses #优化  不优化输入的类文件-dontoptimize #预校验-dontpreverify #混淆时是否记录日志-verbose # 混淆时所采用的算法-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*#保护注解-keepattributes *Annotation*# 保持哪些类不被混淆-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#忽略警告-ignorewarning-ignorewarnings##记录生成的日志数据,gradle build时在本项目根目录输出###apk 包内所有 class 的内部结构-dump proguard/class_files.txt#未混淆的类和成员-printseeds proguard/seeds.txt#列出从 apk 中删除的代码-printusage proguard/unused.txt#混淆前后的映射-printmapping proguard/mapping.txt########记录生成的日志数据,gradle build时 在本项目根目录输出-end#######如果引用了v4或者v7包-dontwarn android.support.**####混淆保护自己项目的部分代码以及引用的第三方jar包library-end#####保持 native 方法不被混淆-keepclasseswithmembernames class * {    native ;}#保持自定义控件类不被混淆-keepclasseswithmembers class * {    public (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 (android.content.Context);    public (android.content.Context, android.util.AttributeSet);    public (android.content.Context, android.util.AttributeSet, int);    public void set*(...);}-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 ;    !private ;    !private ;    private void writeObject(java.io.ObjectOutputStream);    private void readObject(java.io.ObjectInputStream);    java.lang.Object writeReplace();    java.lang.Object readResolve();}#保持枚举 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 ;}#避免混淆泛型 如果混淆报错建议关掉#-keepattributes Signature#移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用,另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制#使用这个配置时,一定要注意 -dontoptimize,配置。#-assumenosideeffects class android.util.Log {#    public static *** v(...);#    public static *** i(...);#    public static *** d(...);#    public static *** w(...);#    public static *** e(...);#}#####################################################################################################################                 以上通用           ######################################################################################################################################################     常用第三方模块的混淆选项         ####################################1 achartengine-dontwarn org.achartengine.**-keep class org.achartengine.** { *;}#2 高德地图-dontwarn com.amap.api.**#3D 地图-keep   class com.amap.api.maps.**{*;} -keep   class com.autonavi.amap.mapcore.*{*;} -keep   class com.amap.api.trace.**{*;}# 定位-keep class com.amap.api.location.**{*;}-keep class com.amap.api.fence.**{*;}-keep class com.autonavi.aps.amapapi.model.**{*;}# 搜索-keep   class com.amap.api.services.**{*;}#2D地图-keep class com.amap.api.maps2d.**{*;}-keep class com.amap.api.mapcore2d.**{*;}# 导航-keep class com.amap.api.navi.**{*;}-keep class com.autonavi.**{*;}#3 butterknife-keep class butterknife.** { *; }-dontwarn butterknife.internal.**-keep class **$$ViewBinder { *; }-keepclasseswithmembernames class * {    @butterknife.* ;}-keepclasseswithmembernames class * {    @butterknife.* ;}#4 smack-dontwarn org.jivesoftware.**-keep class org.jivesoftware.smack.** { *;}-keep class org.jivesoftware.smackx.** { *;}#5 EventBus3.0-keepattributes *Annotation*-keepclassmembers class ** {    @org.greenrobot.eventbus.Subscribe ;}-keep enum org.greenrobot.eventbus.ThreadMode { *; }# Only required if you use AsyncExecutor-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {    (Java.lang.Throwable);}#6 GreenDao-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {public static java.lang.String TABLENAME;}-keep class **$Properties# If you do not use SQLCipher:-dontwarn org.greenrobot.greendao.database.**# If you do not use Rx:-dontwarn rx.**#7FlycoTabLayout 可以混淆#8 mqtt 可以混淆#9 mqtt service 可以混淆#10 gson#如果用用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。-keepattributes Signature# Gson specific classes-keep class sun.misc.Unsafe { *; }# Application classes that will be serialized/deserialized over Gson-keep class com.google.gson.** { *; }-keep class com.google.gson.stream.** { *; }# 如果使用了Gson之类的工具要使被它解析的JavaBean类即实体类不被混淆。-keep class com.app.sample.chatting.api.json.** { *; }-keep class com.app.sample.chatting.bean.** { *; }#11 MPAndroidChart-keep class com.github.mikephil.charting.** { *; }#12 logger可以混淆#13 picasso-keepattributes SourceFile,LineNumberTable-keep class com.parse.*{ *; }-dontwarn com.parse.**-dontwarn com.squareup.picasso.**-keepclasseswithmembernames class * {    native <methods>;}#14 okhttp3-dontwarn com.squareup.okhttp3.**-keep class com.squareup.okhttp3.** { *;}-dontwarn okio.**#15 retrofit2-dontwarn retrofit.**-keep class retrofit.** { *; }-keepattributes Signature-keepattributes Exceptions#16 zxing-dontwarn com.google.zxing.**-keep  class com.google.zxing.**{*;}#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;}

然后执行打包
打包混淆生成后分析选择你的apk文件
android 混淆配置 实例实战项目讲解_第1张图片
可以看到已经混淆了
android 混淆配置 实例实战项目讲解_第2张图片
也可以用反编译工具看看
android 混淆配置 实例实战项目讲解_第3张图片

混淆配置是个细心活,每个工程都不一样,需要根据自己的工程细心配置,否则混淆将会导致工程无法运行

更多相关文章

  1. AndroidManifest.xml文件详解(manifest)
  2. React Native项目结构
  3. Android生成签名文件并用其对apk文件进行签名

随机推荐

  1. Android WebView系列(二)Android和JS互调,Br
  2. Android:Animation
  3. 转:LinearLayout布局
  4. Android studio :Please configure Andro
  5. Android优秀实例源码
  6. [Android] 基于 Linux 命令行构建 Androi
  7. android点滴2
  8. Android(安卓)【真机】与【模拟器】触摸
  9. Android安全机制解析与应用实践
  10. android media库中external的读取