转载:http://www.xue5.com/Mobile/Mobile/705347.html


最近有个同事跟我报怨说,他的系统重装Eclipse使用新的ADT22后,编译的android apk运行总会报ClassNotFoundException错误。我说这怎么可能,谷歌这么大的公司出来的东西怎么可能有这种问题。他说不信你试试,我说试试就试试。我之前用的是ADT21,结果升到ADT22后一运行,晕,不得不服,还果真是ClassNotFound了。

接下来我又换了几个工程编译运行,发现并不一定是所有工程都有错,而是部分使用了第三方JAR包或库工程的APK才会出错,也就是说,NotFound的Class都是在引用的JAR包里的。

接下来自然是在网上找解决办法了,最后也找到了,就是在.classpath里给com.android.ide.eclipse.adt.LIBRARIES加exported=true,或者在工程属性Java Build Path的Order and Export里勾选Android Private Libraries,将相关的库导出到APK里。

问题解决了,但为什么要这么做呢?之前ADT21为何又不需要呢?我另一台机器使用的还是ADT21,因此我把两个版本的ADT工程属性比较了一下,发现还真不一样。下面这个是ADT21的:




其中相互对应的包和源码我用红线相连起来了以便分析。下面这个是ADT22的:



显然,ADT21把所有引用的JAR包都归纳为Android Dependencies,而ADT22是自动将JAR分成Android Private Libraries和Android Dependencies两类了。ADT21不需要勾选Export就能自动将所有引用的JAR包导出并打包到APK,而ADT22则给开发人员选择权限,让开发人员自己决定哪些包要导出到APK里。比如程序面向的是高版本的Android系统,可以选择不需要导出低版本的某些支持包。

显然ADT22比ADT21更合理,用户没勾选的包自然是不应该导出的。但话说回来,其实基本上大部分情况下我们既然把包加到工程里就是需要导出的。在上图情况下,要达到ADT21版本的导出效果,其实只需要把最后两项勾选上,如下图:



这样ADT就会把相应的JAR包里的类也打包到APK里,再运行就不会找不到类了。

其实要说ClassNotFound这个问题,安卓的开发人员应该都已经不是第一次遇上,在从ADT16升级到ADT17时,就已经搞过一回。再ADT17之前,只要是在工程Build Path里的JAR,不管放在哪,ADT都会自动编译进APK里;但到了ADT17就得把要导出的包全放在libs目录下。为此我还翻译了老外一篇文章,参见:http://blog.csdn.net/huzgd/article/details/7604069。

从任何JAR都自动导出,到只导出libs目录的JAR,到只导出勾选的JAR,应该说ADT是在改进,但也带来升级的麻烦。总得来说并不是ADT22有问题,而是ADT21之前的编译工具不规范,ADT22只是更规范。就说嘛谷歌不会这么容易令人失望的,但就是会折腾人。


更多相关文章

  1. Android(安卓)App 使用javax.mail.* API发送email&&Eclipse工程
  2. 【Android实战决】Android沉浸式状态栏实现(下)
  3. android ApiDemos里的Transition3d翻转修复完善
  4. android开发环境建立以及开发工具的使用--怎样使用eclipse来开发
  5. Unity打包——Android和IOS
  6. Android官方技术文档翻译——新构建系统概述
  7. Android(安卓)Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Andro
  8. Android冷启动白屏解析,带你一步步分析和解决问题
  9. Gradle在Android(安卓)Studio 的应用

随机推荐

  1. Android版网络办公系统应用客户端+服务端
  2. andoid小游戏开发
  3. media server分析
  4. 动画效果编程基础
  5. Android中hw_get_module函数分析
  6. Android心得4.5--SQLite数据库--事务处理
  7. Java 队列同步器框架 AQS 实现原理
  8. 【Android学习笔记】LinearLayout嵌套Rec
  9. Tensorflow Mobile Platform - Android
  10. Android开发适配器系列:AutoCompleteTextV