AndroidStudio編譯項目總結

來源:互聯網
上載者:User

標籤:

   還是說下故事背景,公司有個產品,前前後後已經有三個版本了,是基於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的地方出現了ClassNotFoundException,真的,我懵逼了,超級懵逼,連續兩天一直被這個問題折磨,因為我還有個工程,項目結構跟這個極其相似,但是他運行卻沒有問題。

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

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

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

     

 

AndroidStudio編譯項目總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.