Android升級ADT22後會報ClassNotFoundException的原因分析

來源:互聯網
上載者:User

最近有個同事跟我報怨說,他的系統重裝Eclipse使用新的ADT22後,編譯的android apk運行總會報ClassNotFoundException錯誤。我說這怎麼可能,Google這麼大的公司出來的東西怎麼可能有這種問題。他說不信你試試,我說試試就試試。我之前用的是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隻是更規範。就說嘛Google不會這麼容易令人失望的,但就是會折騰人。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.