由于最近使用studio开发的比例大大加重,这次就聊聊studio吧:

       一、什么是混淆?为什么要混淆呢?

               首先混淆就是将代码打乱,在反编译的时候回出现a.b.c等等代码,代码不易泄露。

       二、混淆开关:

minifyEnabled true: 打开混淆控制

       三、排除未使用的资源文件不打入apk中:

 shrinkResources true

      

               proguardFile 'proguard-project.txt' ------> 由于我项目中只有一个混淆文件,所以就这样引入了,如果多的话,还有另外的方法。

       五、混淆代码介绍: 直接粘下我的代码吧... 有具体的讲解

-optimizationpasses 5          # 指定代码的压缩级别
-dontusemixedcaseclassnames   # 是否使用大小写混合
-dontpreverify           # 混淆时是否做预校验
-verbose                # 混淆时是否记录日志

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

-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    # 保持哪些类不被混淆

-keepclasseswithmembernames class * {  # 保持 native 方法不被混淆
    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);
}
-keepclassmembers enum * {     # 保持枚举 enum 类不被混淆
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆
    public static final android.os.Parcelable$Creator *;
    }
 -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>;
    }

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

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

    -keep public class [com.xiaobai.mizar].R$*{
        public static final int *;
    }
    #友盟分享
-dontshrink
-dontoptimize
-dontwarn com.google.android.maps.**
-dontwarn android.webkit.WebView
-dontwarn com.umeng.**
-dontwarn com.tencent.weibo.sdk.**
-dontwarn com.facebook.**


-keep enum com.facebook.**
-keepattributes Exceptions,InnerClasses,Signature
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable

-keep public interface com.facebook.**
-keep public interface com.tencent.**
-keep public interface com.umeng.socialize.**
-keep public interface com.umeng.socialize.sensor.**
-keep public interface com.umeng.scrshot.**

-keep public class com.umeng.socialize.* {*;}
-keep public class javax.**
-keep public class android.webkit.**

-keep class com.facebook.**
-keep class com.umeng.scrshot.**
-keep public class com.tencent.** {*;}
-keep class com.umeng.socialize.sensor.**

-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;}

-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;}

-keep class im.yixin.sdk.api.YXMessage {*;}
-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}

-keep public class [com.xiaobai.mizar].R$*{
    public static final int *;
}

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

-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }

#消除警告 Warning: can't find superclass or interface#Warning: can't find referenced class
-dontwarn  javax.naming.**
-keep class  javax.naming.** { *;}
-dontwarn android.app.Notification
-keep class android.app.Notification { *;}
-dontwarn java.nio.file.**
-keep class java.nio.file.** { *;}
-dontwarn org.xmlpull.v1.**
-keep class org.xmlpull.v1.** { *;}
-dontwarn com.lidroid.**
-keep class com.lidroid.** { *; }

           六、混淆打包的坑:

            1.Warning: can't find referenced field/method '...' in library class (or: can't find referenced classes..)

            2.Warning: library class ... depends on program class ...

            3.Warning: class file ... unexpectedly contains class ...

            4.  Warning:Ignoring InnerClasses attribute for an anonymous inner class

            前两个问题最后用了一种方法解决,所以相当于两个问题,我主要说1和3.

            官网上(http://proguard.sourceforge.net/index.html#/manual/examples.html),关于第一个问题的描述是:

A program class is referring to a field or a method that is missing from a library class. The warning lists both the referencing class and the missing referenced class member. Your compiled class files are inconsistent with the libraries. You may need to recompile the class files, or otherwise upgrade the libraries to consistent versions.

          【android】 If you're developing for Android and ProGuard complains that it can't find a method that is only available in a recent version of the Android run-time, you should change the build target in your project.properties file or build.gradle file to that recent version. You can still specify a different minSdkVersion and a different targetSdkVersion in your AndroidManifest.xml file.


            Alternatively, you may get away with ignoring the inconsistency with the options -ignorewarnings or even -dontwarn. For instance, you can specify "-dontwarn mypackage.MyInconsistentClass".


            Finally, should your program classes reside in the same packages as library classes and should they refer to their package visible class members, then you should also specify the -dontskipnonpubliclibraryclassmembers option.

            大概意思是程序里面用到了库里的类,但库里没有这些类。所以警告了,同时,可以用命令来忽略这些警告。

只是忽略警告的话,实际上还是没有解决问题,后来查找了一些资料,发现是proguard在混淆的时候,把库里的jar包也混淆了,导致程序找不到这些类。于是解决方法就简单了,只需要在proguard.conf配置中用keep命令保留报警的类就行了。但是通常报警的类有成百上千个,不可能一个个保留,有一个简单的方法是只要类的路径前面有相同的根,就可以保留一个总的达到保留下面所有类的目的。比如:


[java] view plaincopy


1. #消除警告 Warning: can't find superclass or interface#Warning: can't find referenced class  
2. -dontwarn org.springframework.**  
3. -keep class org.springframework.** { *;}  
4. -dontwarn org.codehaus.**  
5. -keep class org.codehaus.** { *;}-dontwarn org.apache.**-keep class org.apache.** { *;}

           第2个问题与第一个类似,也是保留相应的类就可以了。

           官网关于第三个问题的描述是:

           The given class file contains a definition for the given class, but the directory name of the file doesn't correspond to the package name of the class. ProGuard will accept the class definition, but the current implementation will not write out the processed version. Please make sure your input classes are packaged correctly. Notably, class files that are in the WEB-INF/classes directory in a war should be packaged in a jar and put in the WEB-INF/lib directory. If you don't mind these classes not being written to the output, you can specify the -ignorewarnings option, or even the -dontwarn option.

            大概意思是类文件的目录名跟类的包名不一致导致了警报,需要确保目录和包名一样才行。特别是WEB-INF/classes目录下的文件需要打成jar包放到WEB-INF/lib 目录下。

            我的这个问题正是出在WEB-INF/classes/....目录这儿,然后我把classes下的类打包放到了lib下,结果然并卵。后来又试了试,发现因为proguard会同时读取classes下的类和lib下的jar包,jar包像上面说的一样是没有问题的,但是classes下的类目录必然要带着classes,然而类名却不是以WEB-INF.classes开头,所以这个警报不可避免会出现。最后消除警报是在-injars里面添加过滤把classes下的类都过滤掉,还有别忘了把jar包添加到lib里。


[java]  view plain copy

1. -injars D:/OrbitService/target/OrbitService.war(!WEB-INF/classes/**)


          第四个问题:

           Warning:Ignoring InnerClasses attribute for an anonymous inner class
           出现这个问题的愿意很简单。
           就是android sdk tools版本过低,升级一下就可以了

          解决办法:
          1、sdk 还是升级
          2、下载ADT  14.0.0版本 (这个版本对eclipse的要求3.5就够了,而且正好能够解决sdk升级的问题) 
          3、安装上adt 即可
                 Help------Install New software

      七、混淆时到底需不需要非得写这样的代码:

                   众所周知现在三方工具越来越多,使开发人员大大减轻负担,包括友盟,sharesdk的出现,解决了三方登录分享等.

                   那么混淆是否也有工具那?

                   答案是肯定的,梆梆加固、爱加密、360加固宝等等都可以使用,很多CTO感觉用其他的平台等于把自己的源码给他们了,那我来说两句,混淆总体来说只是防君子不防小人的东西,如果别人想破解你的代码,你混淆这几句简单的代码有个球用啊??但是如果别人想破解360加固之后的包也可以破解,但肯定比破解我们混淆的要困难很多,如果你说你怕你把代码给了360,那么用户在你后台的账号密码还都给你了呢,用户的信息怎么解释呢... 

                  总结起来个人还是建议使用360加固宝这样的加固软件,而且还支持多渠道打包,还是很方便的...