[转]Android Studio实现代码混淆
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true # 设置是否进行 shrink 等操作(即无用代码压缩),一般设置为 true,使混淆更有效
proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
}
}
2,在proguard-rules.pro中加入以下代码,基本可以涵盖所有:
-optimizationpasses # 指定代码的压缩级别
-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” 错误。
推荐将你所有引用的库(在 app/build.gradle 里)全部不混淆,里面的groupid就是package,将package加入就行了,这是我的示例:
-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.**
忽略了所有库,如果还报警,可以把报警的也全部忽略。
-------------------------------------------------------------------------
ProGuard默认会对第三方库也进行混淆的,而第三方库有的已经混淆过了,有的使用了Java反射技术,所以我们在进行代码混淆的时候要排除这些第三方库。排除对第三方库的混淆需要在混淆规则文件(通常是:proguard-project.txt或proguard.cfg或proguard-rules.pro或proguard-rules.txt也可以是其它的文件名只要在配置文件中将含有混淆规则的文件名配置进去就行了)中添加如下规则:
1.如果使用了Gson之类的工具要使JavaBean类即实体类不被混淆。
2.如果使用了自定义控件那么要保证它们不参与混淆。
3.如果使用了枚举要保证枚举不被混淆。
4.对第三方库中的类不进行混淆
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..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..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..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..jar
-libraryjars libs/httpmime-4.3..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..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一次!一分钟过后,靠!同样的错误提示又来了:
- Warning: com.xxx.bbbb.F.H$3: can't find referenced class com.xxx.bbbb..F.H$com.xxx.bbbb.F.H$_B
- Warning: there were 1 unresolved references to classes or interfaces.
- You may need to specify additional library jars (using '-libraryjars').
- java.io.IOException: Please correct the above warnings first.
- at proguard.Initializer.execute(Initializer.java:321)
- at proguard.ProGuard.initialize(ProGuard.java:211)
- at proguard.ProGuard.execute(ProGuard.java:86)
- at proguard.ProGuard.main(ProGuard.java:492)
这不是坑爹吗?还报错!我以为是顺序不对,把-libraryjars ./libs/xx.jar这句话放到最开头,或者在keep...语句的开头,结果很悲催,也不行。马上看看官方文档的Troubleshooting,发现有说到这个问题后,大喜!我们一起去瞧瞧他怎么说的:
- Warning: can't find superclass or interface
- Warning: can't find referenced class
- If there are unresolved references to classes or interfaces, you most likely forgot to specify an essential library.
- For proper processing, all libraries that are referenced by your code must be specified, including the Java run-time library.
- For specifying libraries, use the -libraryjars option.
- 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.
- 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.
- 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.
- 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
---------------------
作者:微信公众号--共鸣圈
来源:CNBLOGS
原文:https://www.cnblogs.com/welhzh/p/6017434.html
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件
[转]Android Studio实现代码混淆的更多相关文章
- android studio 实现代码混淆
=======本文章属于转载==========原文章地址:http://my.oschina.net/aibenben/blog/370985 这篇文章等是跟大家分享一在Android studio ...
- 【Android】Android Studio 进行代码混淆,打包release APK
整了一天,感觉坑挺多. 1. 选择如图中的选项Android Studio进行签名打包: 2. 填写APP对应的信息:(最好用个文本记下来放在项目中同步给Team) - Key store path: ...
- Android Studio实现代码混淆
1,在build.grandle添加,其中规则写在proguard-rules.pro中,也可以自定义一个文件,将其代替,比如eclipse常用的 proguard-project.txt: bui ...
- 转:Android 2.3 代码混淆proguard技术介绍
ProGuard简介 ProGuard是一个SourceForge上非常知名的开源项目.官网网址是:http://proguard.sourceforge.net/. Java的字节码一般是非常容易反 ...
- Android Studio在代码重构中的妙用
代码重构几乎是每个程序员在软件开发中必须要不断去做的事情,以此来不断提高代码的质量.Android Stido(以下简称AS)以其强大的功能,成为当下Android开发工程师最受欢迎的开发工具,也是A ...
- Android studio打包APK混淆配置
要在打包APK时加入混淆需要在Module中的buid.gradle中加入如下信息 buildTypes { release { minifyEnabled true shrinkResources ...
- Android Studio和eclipse混淆打包总结
最近项目有点闲,考虑到以前的项目没有做过混淆,只是用了加固软件进行加固,为了安全性,准备给项目加上,这里做个总结,都经本人亲自在项目实践,说是为了安全性,这好像说大了,一来项目中没用到什么特别的技术, ...
- Android ProGuard:代码混淆压缩
写这篇文章的目的 一直以来,在项目中需要进行代码混淆时每次都要去翻文档,很麻烦.也没有像写代码那样记得那么多.既然要查来查去,就不如自己捋一捋这个知识点了,被人写的终究还是别人的.所以自己去翻看了很多 ...
- Android studio 显示代码行号 设置
首先我们打开我们的Android Studio. 这时会弹出setting页面,我们选择show line numbers然后点击确定按钮. 此时我们就可以看到代码左侧显示出行号了 我们可 ...
随机推荐
- 转: CentOS上安装LAMP之第一步:Apache环境及安装过程报错解决方案(纯净系统环境)
传送门:http://blog.csdn.net/zhangatle/article/details/77416996 小心坑!填完就懂怎么安装了 Note:要从零开始搭建,就不要嫌中间遇到各种问题 ...
- pug的安装与使用
说明 Pug原名不叫Pug,是大名鼎鼎的jade,后来由于商标的原因,改为Pug,哈巴狗.其实只是换个名字,语法都与jade一样.丑话说在前面,Pug有它本身的缺点--可移植性差,调试困难,性能并不出 ...
- [Vue CLI 3] 配置解析之 css.extract
大家还记得我们在老版本中,对于线上环境配置中会把所有的 css 多打成一个文件: 核心是使用了插件 extract-text-webpack-plugin,方式如下: 第一步都是加载插件 const ...
- Python数据分析与展示[第二周]
matplotlib 有各种可视化的类构成 一般调用 matplotlib.pypolt 这个命令字库 相当于快捷方式 plt.plot(a) 只有一个一维列表 x轴充当列表索引 plt.ylabel ...
- python findall函数
- list reverse
You can make use of the reversed function for this as: >>> array=[0,10,20,40] >>> ...
- windows中Navicat连接centos中的mysql报:1130-Host '192.168.xxx.1' is not allowed to connect to this MySQL解决方法
解决方法: 在centos中登录mysql输入下面指令: grant all PRIVILEGES on *.* to ' WITH GRANT OPTION;
- 【JZOJ4755】【NOIP2016提高A组模拟9.4】快速荷叶叶变换
题目描述 输入 一行,包含两个整数N,M. 输出 1个整数,FHT(N,M) mod 1000000007的值. 样例输入 3 4 样例输出 1 数据范围 对于 40% 的数据,1 ≤ N,M ≤ 1 ...
- Python2 生成器 简介
1. A generator: provide a kind of function that can return an intermediate result ("the next va ...
- Apache CarbonData1.3简介
CarbonData是一种高性能大数据存储方案,支持快速过滤查找和即席OLAP分析,已在20+企业生产环境上部署应用,其中最大的单一集群数据规模达到几万亿.针对当前大数据领域分析场景需求各异而导致的存 ...