AndroidStudio編譯項目總結


   還是說下故事背景,公司有個產品,前前后后已經有三個版本了,是基於Eclipse的項目工程結構,隨着需求變更、產品發展,整個項目也變得非常龐大,當時有五六個library工程,工程引用的第三方Jar也就不說了,一二十個是有的。由於最初這個產品是基於Xamarin開發的,是使用C#作為基礎語言,所以各種原因導致項目使用了大寫包名,其實大寫包名在Eclipse上未出現什么爆炸性的問題,但是等到有一天我想把這個項目移植到AndroidStudio上,就出現了一個致命性的問題,android studio不支持大寫包名,因此只能放棄,至少在我寫博客這個時間點,android studio是無法支持大寫包名的,能編譯成功,但不能運行在設備上。當然這些都是體外話,並不重要。不過提醒各位一點的是,記得哈,Android Studio不支持大寫包名(呵呵,這個很只有少數奇葩情況有人會這么搞吧)。

  問題來了,有一天公司新開業務線,也是需要做產品,由於之前那個工程功能還是比較強大,因此想基於現有工程開發出一個產品,哈哈,多么好的一個時機,這樣就可以把之前的項目更改包名移植到android stduio上了,問題也就隨之而來了,讓我編譯了兩天才把工程編譯成功,我的媽,眼睛都差點跟我看瞎了,下面說下我遇到的問題。

 

1、App工程無法使用本地aar的遠程依賴對象

  之前我不是說公司有五六個library工程嘛,由於項目太多,而且大多是一些工具庫,封裝的一些東西,通常都不會怎么去更改,於是我就想把他們到成jar包文件(帶有資源的就打包成aar),打包這個工程就沒啥說的了,然后我把打包aar給工程引用,發現aar里面遠程依賴的一些第三方庫里面的資源無法訪問,舉例說明,比如我有個LibraryA工程,打包成了a.aar,這個遠程依賴了Retrofit,然后有個管理器類返回一個Retrofit對象,但是我發現app根本就不知道Retrofit的存在,也就是說app工程根本就無法訪問Retrofit這個對象。幾經周折,我偶然發現a.aar中以jar包形式引用的資源是可以被訪問到的,因此我就把所有的遠程依賴都換成了放在libs目錄中的jar或者aar文件,然后進行打包,這個時候工程再引用,就能夠訪問libraryA工程所依賴的資源了。

  但是說實話,這種解決方式實在惡心,而且也對后續工程引用jar上增加了限制,以及jar升級之類的,這些都是問題。后來我再網上各種查找資料,找到一篇文章,當然是另一種方式解決,不過這種方式一樣還是存在前面說的依賴升級的惡心問題,不過這都是小問題,需要升級的話,升級之后再打包編譯即可,也費不了多少事情。

     另外一種解決方式見:http://m.blog.csdn.net/article/details?id=50608677     別人的方式確實要比我找到的方式高級很多,而且別人還圖文並茂,我敗了。

2、Jar包的重復引用

  當你遇到類似 "transformClassesWithJarMergingForDebug" "duplicate entry"等關鍵字的時候,恭喜你,幾乎可以肯定出現jar包的重復引用了。

  如果在比較簡單的工程關系中,這個問題其實還是相對好解決一些,畢竟工程結構清晰,不至於讓人眼花繚亂,把人繞暈,但是也會出現比較難找的情況,下面我就說下我在轉換工程是遇到的一些情況。

     1)、不同版本jar包引用:最簡單的也最容易找到的,也就是不同項目引用了同一個jar包的不同版本,比如一個引用okhttp 1.0,一個引用okhttp2.0,這種情況肯定是要刪除一個的,連Eclipse都不會讓你編譯通過。那你可能就要我,我刪掉jar包的工程怎么辦呢?刪掉了他就沒有這個jar包引用了啊,這里有兩種情況,第一種比如你A和B兩個項目各自引用了兩個不同版本的jar包,並且B依賴A項目,這個時候,讓A去依賴Jar包,B刪除Jar包,其他不用處理,因為這就好比引用傳遞,你依賴了我就不用依賴了。

     2)、遠程依賴的與本地jar包版本不同:這種就復雜一些了,比如我工程中本身依賴了Okhttp-2.4版本的jar包,主要解決文件上傳下載,轉到android stduio上我想換成Retrofit作為網絡請求,這個時候運行的時候就出現重復引用了,因為retrofit2.0默認引用okhttp3.0,所以這種情況你就的知道你的遠程依賴的一些信息,那樣就更利於你解決問題(當然有log會提示什么重復定義了,這個時候根據提示慢慢解決)。

     3)、同版本jar包多副本:這是啥意思,這個就是說同一個文件,你放在A和B的lib目錄中,並且各自引用,這種情況也會出現問題。不過順帶提一句,這種情況在eclipse上並不會有問題,也就是說,eclipse中,你把同一個jar包文件復制多份放在不同的工程中,編譯運行不會有問題,但是Android stduio不行。這個怎么解決呢,當然前面1)問題也提供了一些解決辦法,必然是要清理掉只剩一個,然后懵逼了,因為可能有些項目不存在引用關系,也就是A和B項目不存在依賴關系,但是由於只保留一個jar文件,必然有一個沒有,這個時候有兩種方法,當然原理是一樣,就是刪除其中一個,讓另一個項目引用另外一個項目里面的文件,這個具體怎么寫呢,我也懶得寫代碼,也就一句話,因為這也不是常規做法,常規做法是把工程中引用的jar都放到一個公共目錄中,通常可以選擇是project根目錄下的libs目錄,然后讓其他的工程都引用這里面的,這樣可以避免同個jar多個副本文件的情況。

   4)、貌似就遇到上面些情況。。。

3、工程超過65536方法數限制

  這個在我把工程的網絡框架增加retrofit時出現了這個問題,這個問題的解決辦法,網上一大堆,也好容易解決。

  不過這里有個注意的地方:如果你的工程包含多個Module,那么每個Module都必須支持在工程的build文件中增加 multiDexEnabled true,否則你可能在編譯中遇到xx無法merge等異常。大致如下配置

     defaultConfig {
        ...
        // Enabling multidex support.
        multiDexEnabled true

    } 

  

 

3、Library Module工程無法使用自己工程的資源文件異常

  這個問題着實讓我懵逼了好久,一直到現在,就是一個Library Module工程有一些自定義控件,並且使用了項目本身包含的一些圖片資源。編譯通過了,也正常在手機上運行了,可能當使用到這個自定義控件的地方,就會出現崩潰,經調試在使用R.drawable.xxx的地方出現了NoClassDefFoundError,真的,我懵逼了,超級懵逼,連續兩天一直被這個問題折磨,因為我還有個工程,項目結構跟這個極其相似,但是他運行卻沒有問題。

  之前我一個同學,說讓我嘗試提高gradle的版本,尼瑪說實話,android stduio項目管理方面的,我還真不熟,后來在他的指點下,我更換了版本,從2.4更換2.10,說實話,更換之后連編譯都不通過了,但是我隱約覺得有救了,為啥呢,在2.4上至少能編譯運行,現在連編譯都不通過了,我怎么還能覺得有救呢,直覺,后來我也看了那些錯誤信息,都是一些jar包重復引用的問題,咦,奇了怪了,前面不是解決了一些重復引用問題嗎,怎么這會兒有蹦出這樣的問題來呢,這尼瑪什么鬼,我仔細一看,跟之前的並不一樣,OK,有問題解決問題,跟着前面的步驟,再次解決,就在我還在寫文章記錄的時候(因為都是項目編譯的問題,大家都知道,反復的同步項目,clean,rebuild這些操作,是相當耗時的,需要等待很多時間,因此我就覺得應該寫點什么記錄下之前遇到的問題),就在這個時候,一切問題解決完畢,編譯,運行,尼瑪,問題沒了,我的個天,everything is ok。看來今晚可以安心吃頓肉了。

到此一個龐大結構的項目從eclipse轉移到android studio中正常編譯運行,呼呼。。

PS:關於這個問題,經過前面那一番波折,項目最終正常運行了兩天之后,又莫名其妙的出現同樣的異常,又是一番折騰,這次是處理了項目對fastjson上的依賴,之后又能正常運行了,不過在另外的界面又出現了同樣的異常,但是這次不是資源id引用引起的,又是一番折騰,由於我平時工作用的台式機,因此在台式機上折騰的時候,我嘗試在自己的筆記本上,更新了android studio,gradle,然后再筆記本上運行,莫名奇妙的就沒問題了,所以總體來講,保持IDE &gradle的更新,也許就能夠避免這種沒技術含量卻又異常折磨人的問題。

等后面有時間了在貼上詳細的問題以及過程。

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM