Eclipse打包Android混淆代码降低代码可读性时,出现的Warning:can't find referenced class问题的解决方案

原来用Eclipse打包apk从未想过安全性,即使apk被反编译了,别人也看不懂代码,因为代码的类名都是a,b,c,d等,大大降低了代码的可读性。

这次负责的项目和离线支付有关,所以领导要求必须确保代码的安全性,即使被反编译了,别人也看不懂。这次来被领导派到上海出差,真够辛苦的,但是也是有收获的。

花了我三四个小时,期间碰到了各种问题,最严重的问题就是Warning,但终于成功将代码混淆打包成apk了!好了,闲话不多说了,看看怎么将代码成功混淆:


一、首先必须说明的是,旧版本的ADT,是通过使用文件proguard.cfg来配置,而新版本的ADT是通过使用文件proguard-project.txt来配置。

如果是旧版的ADT,那么在文件project.properties或default.properties中加入proguard.config=proguard-project.cfg;

如果是新版的ADT,那么在文件project.properties中将   #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt    前面的#去掉即可。


二、需指出的是:

旧版的ADT,那么下面的配置内容写在文件proguard-project.cfg中

新版的ADT,俺么下面的配置内容写在文件project.properties中,

以下配置内容转自博友的博客,自己偷懒了下:



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一次!一分钟过后,靠!同样的错误提示又来了:

  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,发现有说到这个问题后,大喜!我们一起去瞧瞧他怎么说的:

  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!而且程序能正确运行
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值