Android Studio实现代码混淆

 1,在build.grandle添加,其中规则写在proguard-rules.pro中,也能够自定义一个文件,将其代替,好比eclipse经常使用的 proguard-project.txt:
buildTypes {
  release {
    signingConfig signingConfigs.release
    minifyEnabled true      # 设置是否进行 shrink 等操做(即无用代码压缩),通常设置为 true,使混淆更有效
    proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
  }
}

2,在proguard-rules.pro中加入如下代码,基本能够涵盖全部:html

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

3,经过 Android Studio进行 混淆代码时,默认已经将 lib目录中的 jar 都已经添加到打包脚本中,因此不须要再次手动添加,不然会出现“ java.io.IOException: The same input jar is specified twice” 错误。java

 

推荐将你全部引用的库(在 app/build.gradle 里)所有不混淆,里面的groupid就是package,将package加入就好了,这是个人示例:react

-keep class org.greenrobot.greendao.** { *; }
-dontwarn org.greenrobot.greendao.**
-keep class com.jakewharton.** { *; }
-dontwarn com.jakewharton.**
-keep class io.reactivex.** { *; }
-dontwarn io.reactivex.**
-keep class org.jsoup.** { *; }
-dontwarn org.jsoup.**
-keep class com.squareup.retrofit2.** { *; }
-dontwarn com.squareup.retrofit2.**
-keep class com.scottyab.** { *; }
-dontwarn com.scottyab.**
-keep class com.pddstudio.preferences.encrypted.** { *; }
-dontwarn com.pddstudio.preferences.encrypted.**

忽略了全部库,若是还报警,能够把报警的也所有忽略。android

 

-------------------------------------------------------------------------正则表达式

ProGuard默认会对第三方库也进行混淆的,而第三方库有的已经混淆过了,有的使用了Java反射技术,因此咱们在进行代码混淆的时候要排除这些第三方库。排除对第三方库的混淆须要在混淆规则文件(一般是:proguard-project.txt或proguard.cfg或proguard-rules.pro或proguard-rules.txt也能够是其它的文件名只要在配置文件中将含有混淆规则的文件名配置进去就好了)中添加以下规则:算法

1.若是使用了Gson之类的工具要使JavaBean类即实体类不被混淆。apache

2.若是使用了自定义控件那么要保证它们不参与混淆。json

3.若是使用了枚举要保证枚举不被混淆。api

4.对第三方库中的类不进行混淆app

a.混淆时保护引用的第三方jar包

如:-libraryjars libs/baidumapapi_v3_2_0.jar  #保护引用的第三方jar包不被混淆

注意:在使用Eclipse+ADT时须要加入-libraryjars libs/...,若是你是使用Android Studio开发的项目则不须要加入libs包中的jar包,这是由于,经过Android Studio进行混淆代码时,默认已经将 lib目录中的 jar 都已经添加到打包脚本中,因此不须要再次手动添加,不然会出现“ java.io.IOException: The same input jar is specified twice” 错误。

b.混淆时保护第三方jar包中的类不被混淆

如:-keep class com.baidu.** { *; }         #保持com.baidu.**这个包里面的全部类和全部方法不被混淆。

-dontwarn com.baidu.**          #让ProGuard不要警告找不到com.baidu.**这个包里面的类的相关引用

附:下面是开发中用到的一些混淆规则,你们能够根据须要复制到本身的项目中的混淆规则的文件中:

################common###############  
-keep class com.jph.android.entity.** { *; } #实体类不参与混淆  
-keep class com.jph.android.view.** { *; } #自定义控件不参与混淆  
  
################baidu map###############  
-libraryjars libs/baidumapapi_v3_2_0.jar  
-libraryjars libs/locSDK_5.0.jar  
-keep class com.baidu.** { *; }  
-keep class vi.com.gdi.bgl.android.**{*;}  
-dontwarn com.baidu.**  
  
  
################afinal##################  
#-libraryjars libs/afinal_0.5_bin.jar  
#-keep class net.tsz.afinal.** { *; }   
#-keep public class * extends net.tsz.afinal.**    
#-keep public interface net.tsz.afinal.** {*;}  
#-dontwarn net.tsz.afinal.**  
  
################xutils##################  
-libraryjars libs/xUtils-2.6.14.jar  
-keep class com.lidroid.xutils.** { *; }   
-keep public class * extends com.lidroid.xutils.**    
-keepattributes Signature  
-keepattributes *Annotation*  
-keep public interface com.lidroid.xutils.** {*;}  
-dontwarn com.lidroid.xutils.**  
-keepclasseswithmembers class com.jph.android.entity.** {  
    <fields>;  
    <methods>;  
}  
  
################支付宝##################  
-libraryjars libs/alipaysecsdk.jar  
-libraryjars libs/alipayutdid.jar  
-libraryjars libs/alipaysdk.jar  
-keep class com.alipay.android.app.IAliPay{*;}  
-keep class com.alipay.android.app.IAlixPay{*;}  
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}  
-keep class com.alipay.android.app.lib.ResourceMap{*;}  
  
################gson##################  
-libraryjars libs/gson-2.2.4.jar  
-keep class com.google.gson.** {*;}  
#-keep class com.google.**{*;}  
-keep class sun.misc.Unsafe { *; }  
-keep class com.google.gson.stream.** { *; }  
-keep class com.google.gson.examples.android.model.** { *; }   
-keep class com.google.** {  
    <fields>;  
    <methods>;  
}  
-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();  
}  
-dontwarn com.google.gson.**  
  
  
  
################httpmime/httpcore##########  
-libraryjars libs/httpcore-4.3.2.jar  
-libraryjars libs/httpmime-4.3.5.jar  
-keep class org.apache.http.** {*;}  
-dontwarn org.apache.http.**  
  
####################jpush##################  
-libraryjars libs/jpush-sdk-release1.7.1.jar  
-keep class cn.jpush.** { *; }  
-keep public class com.umeng.fb.ui.ThreadView { } #双向反馈功能代码不混淆  
-dontwarn cn.jpush.**  
-keepclassmembers class * {  
    public <init>(org.json.JSONObject);  
}  
 #不混淆R类  
-keep public class com.jph.android.R$*{   
    public static final int *;  
}  
-keepclassmembers enum * {  
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
}  
  
####################umeng##################  
-libraryjars libs/umeng-analytics-v5.2.4.jar  
-keep class com.umeng.analytics.** {*;}  
-dontwarn com.umeng.analytics.**  
  
#-keep public class * extends com.umeng.**    
#-keep public class * extends com.umeng.analytics.**    
#-keep public class * extends com.umeng.common.**    
#-keep public class * extends com.umeng.newxp.**   
-keep class com.umeng.** { *; }    
-keep class com.umeng.analytics.** { *; }    
-keep class com.umeng.common.** { *; }    
-keep class com.umeng.newxp.** { *; }   
  
-keepclassmembers class * {  
   public <init>(org.json.JSONObject);  
}  
-keep class com.umeng.**  
  
-keep public class com.idea.fifaalarmclock.app.R$*{  
    public static final int *;  
}  
  
-keep public class com.umeng.fb.ui.ThreadView {  
}  
  
-dontwarn com.umeng.**  
  
-dontwarn org.apache.commons.**  
  
-keep public class * extends com.umeng.**  
  
-keep class com.umeng.** {*; }  
  
####################universal-image-loader########  
-libraryjars libs/universal-image-loader-1.9.3.jar  
-keep class com.nostra13.universalimageloader.** {*;}  
-dontwarn com.nostra13.universalimageloader.**  
  
  
####################zxing#####################  
-libraryjars libs/zxing.jar  
-libraryjars libs/zxing_apply.jar  
-keep class com.google.zxing.** {*;}  
-dontwarn com.google.zxing.**  
  
####################BASE64Decoder##################  
-libraryjars libs/sun.misc.BASE64Decoder.jar  
  
####################support.v4#####################  
-libraryjars libs/android-support-v4.jar  
-keep class android.support.v4.** { *; }  
-dontwarn android.support.v4.**  
  
###################other####################  
# slidingmenu 的混淆  
-dontwarn com.jeremyfeinstein.slidingmenu.lib.**  
-keep class com.jeremyfeinstein.slidingmenu.lib.** { *; }  
# ActionBarSherlock混淆  
-dontwarn com.actionbarsherlock.**  
-keep class com.actionbarsherlock.** { *; }  
-keep interface com.actionbarsherlock.** { *; }  
-keep class * extends java.lang.annotation.Annotation { *; }  
-keepclasseswithmembernames class * {  
    native <methods>;  
}  
  
-keep class com.jph.android.entity.** {  
    <fields>;  
    <methods>;  
}  
  
-dontwarn android.support.**  
-dontwarn com.slidingmenu.lib.app.SlidingMapActivity  
-keep class android.support.** { *; }  
-keep class com.actionbarsherlock.** { *; }  
-keep interface com.actionbarsherlock.** { *; }  
-keep class com.slidingmenu.** { *; }  
-keep interface com.slidingmenu.** { *; }  

 

 若是打包的时候出现警告:can't find referenced class  怎么办?解决方案以下:

1. 问题的产生缘由

           "类1 can't find referenced class 类2" 字面上的意思就是类1找不到类2的引用;接着再看下去"You may need to specify additional library jars (using '-libraryjars').";

噢,原来这么简单呀,他说我须要使用-libraryjars加上项目中使用到的第三方库就OK了。好!立刻把"-libraryjars ./libs/xx.jar"这段代码加入到proguard.cfg配置文件里面去,
再export一次!一分钟事后,靠!一样的错误提示又来了:

[java]  view plain copy
  1. Warning: com.xxx.bbbb.F.H$3: can't find referenced class com.xxx.bbbb..F.H$com.xxx.bbbb.F.H$_B  
  2. Warning: there were 1 unresolved references to classes or interfaces.  
  3. You may need to specify additional library jars (using '-libraryjars').  
  4. java.io.IOException: Please correct the above warnings first.  
  5.     at proguard.Initializer.execute(Initializer.java:321)  
  6.     at proguard.ProGuard.initialize(ProGuard.java:211)  
  7.     at proguard.ProGuard.execute(ProGuard.java:86)  
  8.     at proguard.ProGuard.main(ProGuard.java:492)  


          这不是坑爹吗?还报错!我觉得是顺序不对,把-libraryjars ./libs/xx.jar这句话放到最开头,或者在keep...语句的开头,结果很悲催,也不行。立刻看看官方文档的Troubleshooting,发现有说到这个问题后,大喜!咱们一块儿去瞧瞧他怎么说的:

[java]  view plain copy
  1. Warning: can't find superclass or interface  
  2. Warning: can't find referenced class  
  3. If there are unresolved references to classes or interfaces, you most likely forgot to specify an essential library.   
  4. For proper processing, all libraries that are referenced by your code must be specified, including the Java run-time library.   
  5. For specifying libraries, use the -libraryjars option.  
  6. For example, if ProGuard complains that it can't find a javax.crypto class, you probably still have to specify jce.jar, next to the more common rt.jar.  
  7. If you're missing a library and you're absolutely sure it isn't used anyway, you can try your luck with the -ignorewarnings option, or even the -dontwarn option. Only use these options if you really know what you're doing though.  
  8. For example, if you're developing for Android, and ProGuard complains that it can't find a java.awt class, then some library that you are using is referring to java.awt.   
  9. This is a bit shady, since Android doesn't have this package at all, but if your application works anyway, you can let ProGuard accept it with "-dontwarn java.awt.**".  


2.官方对于这个问题的解释:

          若是存在未解决的类或者接口的引用的话,你颇有可能忘记指定一些必要的库了。正确的处理方法是在你代码里引用到的全部库都必需要在配置文件中指定,包括Java运行库,使用-libraryjars选项来指定这些库。

          看到这里,你明白了刚刚为何提示You may need to specify additional library jars (using '-libraryjars').了吧,目的就是在配置文件里面加上项目中所使用到的第三方库。但是,你这是坑爹呀,我明明给全部库都加上-libraryjars参数指定了,结果仍是报Warning: com.xxx.bbbb.F.H$3: can't find referenced class com.xxx.bbbb..F.H$com.xxx.bbbb.F.H$_B这个错啊,打包不了!

 

          好,咱们再看下去...

 

          接着他给咱们举个例子:若是ProGuard说它找不到javax.crypto class这个类,你可能还须要指定jce.jar包,紧接着还要指定更经常使用的rt.jar包。换句话说,javax.crypto class这个类里面所引用到的类不但在jce.jar包里面,还在rt.jar包里面。

但是我项目中用到的全部第三方包都使用-libraryjars指定了呀!这个方法解决不了个人问题,不知道解决得了你的问题不?

 

          解决不了的话,再看下去...

 

          若是你缺乏了某个库,并且你绝对确定本身没有用到这个库里面的类的话,你能够试试你的运气,使用-ignorewarnings或者-dontwarn选项!-dontwarn我试过了,加上
-dontwarn com.xxx.bbbb.**以后确实没有报错,能够打包出来了!呵呵,别高兴得太早,你拿你这样打包好了的包去运行一下试试看?若是运气好的话,程序没有执行到找不到的类那里就不会报错,若是运气很差的话执行到那里了就会抛ClassNotFoundException!哼哼,怕了没?

          咱们身为备受瞩目的程序猿,确定要有职业道德的,总不能编译出来的程序要使用到用户的运气+人品才能保证不出错吧!!^_^

其实,我明白他说的意思的,就是说你要绝对确保这个类没有被你的程序中使用到才可使用-ignorewarnings或者-dontwarn选项,接着,他又举了个例子了: 好比你开发的是Android项目,可是打包时ProGuard抱怨找不到java.awt里面的某些类,多是由于你使用的某些库要用到java.awt包里面的类,众所周知,Android压根就没有java.awt这个包,它是J2SE里面的包,咱们Android程序固然不须要这个包也能很好的运行了,此时,你能够用-dontwarn java.awt.**来屏蔽掉全部关于java.awt的警告他举这个例子是为了说明一个理论:当你绝对肯定本身的代码没有用到报错的这个类后,可使用-dontwarn com.xx.bbb**来屏蔽警告信息



3.总结出官方对于
Warning: can't find superclass or interface
Warning: can't find referenced class

这两个问题的解决方法:

1.要把你项目中所引入的第三方jar包使用"-libraryjars 包路径"指定好。
2.仍是报错的话,确保报错的类没有在你的项目中使用到,使用"-dontwarn 类名正则表达式"屏蔽警告。
完了?但是我还想问:第一步作完后仍是报错,并且这个类在我项目中真的有用到,不能使用"-dontwarn .."屏蔽警告啊??


4.说了这么久,终于开始说解决方案了:

          其实找不到引用的这个类是第三方包里面的,并且不少时候咱们只须要混淆本身写的代码就好了,第三方包的代码就是否要打乱就不要管了。嘻嘻,这叫作"只扫本身门前雪,甭管他人瓦上霜",

咱们可使用
-dontwarn com.xx.bbb.**
-keep class com.xx.bbb.** { *;}

参数来保持第三方库中的类而不乱,-dontwarn和-keep 结合使用,意思是保持com.xx.bbb.**这个包里面的全部类和全部方法而不混淆,接着还叫ProGuard不要警告找不到com.xx.bbb.**这个包里面的类的相关引用。
配置好后,从新打包,一切OK!并且程序能正确运行。示例:

----------------------------------------- question ------------------------------------------------

After some updates in Android SDK manager I try make signed apk and get this:

ProGuard: [] Warning: com.google.android.gms.auth.GoogleAuthUtil: can't find referenced class com.welhzh.android.gms.R ProGuard: [] Warning: com.google.android.gms.auth.GoogleAuthUtil: can't find referenced class com.google.android.gms.R$string ... etc.

If set -dontwarn com.welhzh.android.gms.** compiling is OK. But after run I get error many reports like this (from many devices):

Caused by: android.view.InflateException: Binary XML file line #32:  Error inflating class com.google.android.gms.common.SignInButton

On my devices all ok. Before update I have not ProGuard warnings and all work perfectly. How it fix?

----------------------------------------- answer ------------------------------------------------

Although adding this to proguard-project.txt file works, it keeps all classes.

-keep class com.welhzh.android.gms.** { *; }
-dontwarn com.welhzh.android.gms.**

I prefer this, which makes apk file size much smaller  (通常状况下别用这个) :

-keep public class com.welhzh.android.gms.* { public *; }
-dontwarn com.welhzh.android.gms.**

Also note up to date Google Play Proguard notification here:http://developer.android.com/google/play-services/setup.html#Proguard

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

 

 若是上面的致使app运行时崩溃,能够来狠一点的,指定proguard只混淆某些package或类:

-keep class !com.foo.**,!com.bar.** { *; }
-dontwarn !com.foo.**,!com.bar.**     # 这句比较危险,不提示任何warning
相关文章
相关标签/搜索