Android 混淆问题总结
转载 地址:http://m.blog.csdn.net/blog/wwangliw/8874497
有添加个人经验信息 共勉
混淆文件编写:保存为.pro文件
-injars androidtest.jar【jar包所在地址】
-outjars out【输出地址】
-libraryjars ‘D:\android-sdk-windows\platforms\android-9\android.jar’ 【引用的库的jar,用于解析injars所指定的jar类】
#以上三条不经常用
-optimizationpasses 5
-dontusemixedcaseclassnames 【混淆时不会产生形形色色的类名 】
-dontskipnonpubliclibraryclasses 【指定不去忽略非公共的库类。 】
-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
-keep public abstract interface com.asqw.android.Listener{
public protected ; 【所有方法不进行混淆】
}
-keep public class com.asqw.android{
public void Start(java.lang.String); 【对该方法不进行混淆】
}
-keepclasseswithmembernames class * {
【保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)】
native ;
}
-keepclasseswithmembers class * { 【保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。】
public (android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {【保护指定类的成员,如果此类受到保护他们会保护的更好 】
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {【保护指定的类文件和类的成员】
public static final android.os.Parcelable$Creator *;
}
Android引用第三方jar包混淆时打包报错(can’t find referenced class)
项目打包的时候,总是失败,提示Proguard returned with error code 1. See console。然后看控制台,报出好多can’t find referenced class…
场景:项目中引用了第三方的jar包
原因:第三方jar包中引用了好多oracle发布的java标准中(也就是我们常用的JDK)包含的类,但是Android的java标准和oracle的不一样,android.jar里面去掉了oracle java标准中好多用不到的包和类。
解决办法:首先要把你项目中所引入的第三方jar包使用"-libraryjars 包路径"指定好。然后,用-dontwarn com.xx.bbb.**
-keep class com.xx.bbb.** { *;}告诉proguard.cfg不用混淆指定的jar包,也不用提示这个包所报出的错。这样就ok了。
注意:要是用dontwarn取消指定包报错之前,你要保证第三方引用的类在你的项目中没有用到。
Android混淆后项目运行的时候出现异常(混淆之前没有该异常)
1、ClassNotFoundException,NoSuchMethodError
原因:这种异常会在好多情况下出现,比如:本地代码通过反射调用其他的类,但是经过了混淆之后,就会出现如上异常;调用了JNI之后,C或者C++和java代码进行交互的时候找不到java的类或者方法,导致发生了异常…等等,还有好多。
解决办法:只需要将被调用的java类标注为不混淆即可。 -keep class package.classname{*;}
2、ExceptionInInitializerError
原因:这是由于类初始化的时候发生了异常。
解决办法:找到具体是哪里的类哪个方法哪个类初始化的时候发生的异常,然后解决问题。
注:遇到这个错误,首先要确认是不是因为第三方的jar包导致的。如果不是的话,就找本地代码,看是不是写的有问题。如果确实是因为第三方jar包的代码导致的,尽量找到源码或者反编译,查看问题到底是什么引起的,然后找到相应的配置在proguard里面配置。
例如:我们项目中碰到过一个问题,就是因为第三方的jar包里面有一个字段初始化的时候报了空指针,然后导致我们的代码报了上面的错。当时很奇怪,为什么第三方的jar包还能报错,最后调查了之后才发现,是因为人家用到了类的注解,而proguard在混淆优化的时候把注解去掉了,所以报了空指针,只需要在proguard里面加上保护注解就可以了-keepattributes Annotation
3、 ClassCastException
原因:类强制转换的时候出错。
解决办法:找到代码,看是代码写的问题,还是混淆后的问题。如果没有混淆正常运行的话,一般都是因为混淆后遇到了各种问题才报的错。我们项目中遇到的问题是因为没有让proguard保持泛型,所以强转的时候报错。只需要在proguard文件里面加上泛型即可-keepattributes Signature
4、Resources
N
o
t
F
o
u
n
d
E
x
c
e
p
t
i
o
n
(
r
e
s
o
u
r
c
e
n
o
t
f
o
u
n
d
)
资
源
没
有
找
到
,
是
因
为
第
三
方
j
a
r
包
或
者
自
己
的
代
码
是
通
过
反
射
获
得
R
文
件
中
的
资
源
,
所
以
需
要
将
R
文
件
屏
蔽
掉
原
因
:
代
码
进
行
了
混
淆
,
R
文
件
没
有
了
,
所
以
通
过
反
射
获
取
的
R
文
件
找
不
到
解
决
办
法
:
在
p
r
o
g
u
a
r
d
文
件
里
设
置
不
混
淆
R
文
件
−
k
e
e
p
c
l
a
s
s
∗
∗
.
R
NotFoundException(resource not found) 资源没有找到,是因为第三方jar包或者自己的代码是通过反射获得R文件中的资源,所以需要将R文件屏蔽掉 原因:代码进行了混淆,R文件没有了,所以通过反射获取的R文件找不到 解决办法:在proguard文件里设置不混淆R文件 -keep class **.R
NotFoundException(resourcenotfound)资源没有找到,是因为第三方jar包或者自己的代码是通过反射获得R文件中的资源,所以需要将R文件屏蔽掉 原因:代码进行了混淆,R文件没有了,所以通过反射获取的R文件找不到 解决办法:在proguard文件里设置不混淆R文件 −keepclass∗∗.R* { *; }
Android API 16 或 cocos 3.x 之后的混淆问题(主要是JNI 问题)
1.在libc Fatal signal 11 (SIGSEGV) 问题中
因为cocox 3.x 之后生成的android项目 是继承的NativeActivity 而不是Activity 同时 在 org.cocos2dx.lib下的文件都同时采用了JNI反射机制
并非常规启动和调用,都成为了JNI调用的代码。
解决方法:在混淆文件中 加入 -keep class org.cocos2dx.lib.** { *; } 都不要混淆。