赞
踩
在实际开发过程中,我们经常会遇到以下问题而导致程序运行时崩溃:
- E AndroidRuntime: FATAL EXCEPTION: main
- E AndroidRuntime: Process: com.test.MainActivity, PID: 5172
- E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/com/xxx/xxx/TestUtil;
- E AndroidRuntime: at com.test.app.MainActivity.onCreate(MainActivity.java :12)
- E AndroidRuntime: at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
- E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6998)
- E AndroidRuntime: at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
- E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
- E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
- E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:205)
- E AndroidRuntime: at android.os.Looper.loop(Looper.java:294)
- E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8177)
- E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
- E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:570)
- E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
- E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: com.xxx.xxx.TestUtil
上述例子崩溃原因:在com.test.MainActivity里找不到com.xxx.xxx.TestUtil这个类。
NoClassDefFoundError问题的原因:一般是在编译时可以找到对应的类,但是在运行时找不到对应的类。
下面主要说一下遇到NoClassDefFoundError问题该怎么分析并解决。
jar包的引用方式一般有LOCAL_STATIC_JAVA_LIBRARIES、LOCAL_JAVA_LIBRARIES这两种,下面分别对这两种引用方式遇到NoClassDefFoundError可能的原因进行分析说明。
1.LOCAL_STATIC_JAVA_LIBRARIES方式引用jar包
这种引用方式表示把外部的java库直接编译到本模块中,在运行时可以直接从本模块找到对应的类。所以需要的java 库的东西一般在本模块中的编译产物中可以找到。
这类引用一般出现NoClassDefFoundError问题的原因一般是:该jar包或者对应的类没有在模块中被编译出来。
首先需要确认模块对应路径是否存在需要的对应类,路径一般在源码下:
out/target/common/obj/JAVA_LIBRARIES/xxx_intermediates/
在这个路径下查找java 库中对应的类是否存在,如果不存在,那么说明你需要的类没有编译出来,需要进一步确认类为什么没有编译出来,是路径错误或者是拼写原因,或者时引用时的注释问题。
我遇到过一次因为注释原因导致jar包没有被编译进去:
- LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-v4 \
- android-support-v7-recyclerview \
- # android-support-v7-appcompat \
- android-support-annotations
我只注释了appcompat包,但是运行的时候一直找不到android-support-annotations里的某个类,原因就是误用注释,这种注释其实就相当于:
-
-
- LOCAL_STATIC_JAVA_LIBRARIES :=android-support-v4 android-support-v7-recyclerview # android-support-v7-appcompat android-support-annotations
-
这种会把后面的一起注释掉,所以这种添加多个jar包时尽量不要注释,直接删掉,或者将需要的jar包挪到最上面,避免因注释而导致下面的jar包无法被添加。
2.LOCAL_JAVA_LIBRARIES方式引用jar包
这种方式引用的java库在编译时可以找到,但并不打包到本模块,在运行时需要从别的地方查找,所以一般会生成一个单独的jar包。
(1)首先还是要确认这个jar包有没有生成(这个时候jar的路径可能不在应用程序内,而是一个单独的路径),如果没有,则需要添加。如果存在,那么可能是第二种情况
(2)如果jar包存在,但是还是有NoClassDefFoundError问题,可能是没有添加uses-library标签导致的。
这个标签用于指定程序必须链接的共享库。该元素告诉系统将库的代码包含在包的类加载器中。所有的android软件包(例如android.app,android.content,android.view和android.widget)都在默认库中,所有应用程序都会自动链接。但是,某些包位于不自动链接的单独库中(对于如何链接共享库,可以参考Android 引用共享库的方式-CSDN博客)如果要使用,则必须要添加uses-library标签。
在程序的AndroidManifest.xml文件里添加:
<uses-library android:name="com.xxx.xxx" android:required="false" />
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。