[O]
安卓應用在低版本(V2.3.6)系統上運行時報錯: java.lang.NoClassDefFoundError
完整錯誤信息如下:
05-29 13:56:13.687: E/AndroidRuntime(3538): FATAL EXCEPTION: main 05-29 13:56:13.687: E/AndroidRuntime(3538): java.lang.NoClassDefFoundError: com.uustudio.unote.android.BaseApplication$1 05-29 13:56:13.687: E/AndroidRuntime(3538): at com.uustudio.unote.android.BaseApplication.onCreate(BaseApplication.java:109) 05-29 13:56:13.687: E/AndroidRuntime(3538): at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:969) 05-29 13:56:13.687: E/AndroidRuntime(3538): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3276) 05-29 13:56:13.687: E/AndroidRuntime(3538): at android.app.ActivityThread.access$2200(ActivityThread.java:117) 05-29 13:56:13.687: E/AndroidRuntime(3538): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:973) 05-29 13:56:13.687: E/AndroidRuntime(3538): at android.os.Handler.dispatchMessage(Handler.java:99) 05-29 13:56:13.687: E/AndroidRuntime(3538): at android.os.Looper.loop(Looper.java:130) 05-29 13:56:13.687: E/AndroidRuntime(3538): at android.app.ActivityThread.main(ActivityThread.java:3687) 05-29 13:56:13.687: E/AndroidRuntime(3538): at java.lang.reflect.Method.invokeNative(Native Method) 05-29 13:56:13.687: E/AndroidRuntime(3538): at java.lang.reflect.Method.invoke(Method.java:507) 05-29 13:56:13.687: E/AndroidRuntime(3538): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 05-29 13:56:13.687: E/AndroidRuntime(3538): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 05-29 13:56:13.687: E/AndroidRuntime(3538): at dalvik.system.NativeStart.main(Native Method)
簡化后:
E/AndroidRuntime(3538): FATAL EXCEPTION: main E/AndroidRuntime(3538): java.lang.NoClassDefFoundError: com.uustudio.unote.android.BaseApplication$1 at com.uustudio.unote.android.BaseApplication.onCreate(BaseApplication.java:109) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:969) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3276) at android.app.ActivityThread.access$2200(ActivityThread.java:117) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:973) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.app.ActivityThread.main(ActivityThread.java:3687) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) at dalvik.system.NativeStart.main(Native Method)
1. 一種解決方案如鏈接:http://blog.csdn.net/leehong2005/article/details/9407111
未生效
2. 一種解決方案:Properties->Java Build Path 選擇Source分頁添加Libs路徑,從而將第三方jar包打包進apk
未生效
3. 過程中出現新問題:Unable to execute dex: Multiple dex files define Lcom/myapp/R$array;
解決方案:http://stackoverflow.com/questions/7870265/unable-to-execute-dex-multiple-dex-files-define-lcom-myapp-rarray
4. 一種解決方案,此種應該是離問題原因很近的:http://blog.csdn.net/tianjian4592/article/details/43467283
依然未生效,但可基本判斷是配置沖突或配置未生效造成的,需要clean之后重新配置。
(然而測試之后發現並非如此...)
以上解決辦法均針對安卓工程引用第三方jar包這一原因,我的情況是在部分機型(高版本安卓系統)及模擬器運行正常,在部分機型(安卓系統2.3.6)測試時出現問題,若是上述原因,則所有機型均無法正常運行才對,故排除。
5. 一種原因分析:AsyncTask陷阱之:Handler,Looper與MessageQueue的詳解
在該問題案例中,程序在安卓2.3版本的機器上無法運行,在4.0及以上版本運行OK,其原因是程序中的Handler對象未進行BindApplication,而4.0及以上版本系統會自動進行該操作,該文章相關內容如下:
從2.3運行時的Stacktrace來看原因是在非UI線程中操作了UI組件。不對呀,神奇 啊,AsyncTask#onProgressUpdate()和AsyncTask#onPostExecute()的文檔明明寫着這二個回調是在UI 線程里面的嘛,怎么還會報出這樣的異常呢!
AsyncTask設計出來執行異步任務卻又能與主線程通訊,它的內部有一個 InternalHandler是繼承自Handler的靜態成員sHandler,這個sHandler就是用來與主線程通訊的。看下這個對象的聲 明:private static final InternalHandler sHandler = new InternalHandler();而InternalHandler又是繼承自Handler的。所以本質上講sHandler就是一個 Handler對象。Handler是用來與線程通訊用的,它必須與Looper和線程綁定一起使用,創建Handler時必須指定Looper,如果不 指定Looper對象則使用調用棧所在的線程,如果調用棧線程沒有Looper會報出異常。看來這個sHandler是與調用new InternalHandler()的線程所綁定,它又是靜態私有的,也就是與第一次創建AsyncTask對象的線程綁定。所以,如果是在主線程中創建 的AsyncTask對象,那么其sHandler就與主線程綁定,這是正常的情況。在此例子中AsyncTask是在衍生線程里創建的,所以其 sHandler就與衍生線程綁定,因此,它自然不能操作UI元素,會在onProgressUpdate()和onPostExecute()中拋出異常。
以上例子有異常的原因就是在衍生線程中創建了SimpleAsyncTask對象。至於為什么在4.0版本上沒有問題,是因為4.0 中在ActivityThread.main()方法中,會進行BindApplication的動作,這時會用AsyncTask對象,也會創建 sHandler對象,這是主線程所以sHandler是與主線程綁定的。后面再創建AsyncTask對象時,因為sHandler已經初始化完了,不 會再次初始化。至於什么是BindApplication,為什么會進行BindApplication的動作不影響這個問題的討論。AsyncTask的缺陷及修改方法。
這其實是AsyncTask的隱藏的Bug,它不應該這么依賴開發者,應該強加條件限制,以保證第一次AsyncTask對象是在主線程中創建。
該問題及原因描述與我遇到的情況及錯誤日志信息極為相近,為驗證之,新建安卓2.2和2.3版本的模擬器並運行代碼。
- 在安卓2.2版本系統的模擬器下運行,報出同樣錯誤及Log信息。