最近在重構之前的一個Android項目,導入後沒法運行,報錯以下:html
Caused by: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: D:\...java
稍微操做一下之後,又獲得報錯以下:android
Error: Program type already present: android.support.v4.app.BackStackRecord$Opgit
找了不少的文章,也看了不少的技術文檔,大體發現了緣由github
之因此產生這樣的問題,我我的認爲,能夠簡單地歸納爲:app
你的Android Studio更新,包括你的Gradle以及對應版本的更新,隨之而更新,帶動了Gradle中某些特性的升級。問題實際上是出在你的dependency裏,也就是說你的依賴關係出了問題。gradle
打開你的Project視圖下的工程目錄,查看Project下的build.gradle文件,操做方法以下圖所示ui
若是這個文件很長,翻到下面的這個地方.net
此處以compile開頭的語句(也有多是以implementation開頭,有細微的差異,具體區別見個人另一篇博客https://blog.csdn.net/qq_24118527/article/details/82873812)表示當前你Project的依賴文件,能夠簡單地理解成外部的庫插件
你能夠直接去github上面找對應庫的issue,會有人提供相應的解決方法(這個問題不少人都遇到了),好比這種解決方法:
這種解決方法其實是處理了一些庫之間的依賴關係
能夠簡單的理解爲,我以前有一句語句引用了android.support.v4這個庫
如今我引用了一個新的庫,可是這個庫裏面也引用了android.support.v4這個庫
那麼同時引用的這兩個庫就會產生一些衝突,此時能夠用如上圖所示的方法
至關於我在新引用的庫裏面exclude掉一些重複的東西
這時就比較麻煩了,也就是我遇到的狀況
我這個Project中用到的庫可能有10來個吧,很難肯定究竟是哪一個庫出了問題,一個個去找也會比較麻煩
在解決這個問題的過程當中,我查看了許多的博客以及官方文檔,可是依然沒有一個完美的解決方案,可是摸索出了一個折衷的方法,僅供你們參考
首先你要查看你的三個version,也就是:
compileSdkVersion
buildToolsVersion
targetSdkVersion
這三個version的含義就是字面意思,不細說了,總之這三個version最好保持一致
查看這三個version的方法以下圖所示(這個是我更改之後)
在我更改之前,個人三個version分別是
compileSdkVersion 28
buildToolsVersion 28.02
targetSdkVersion 28
接下來你要查看你兩個的gradle version(注意是查看不是更改,更改的方法下面會說)
你能夠簡單地理解成,Gradle是一款軟件產品,不只僅是Android在用這個款產品,別的公司(好比Adobe等,能夠在官網查)也在用這個產品,這個產品是在不停地迭代更新的,這個版本就是所謂的Gradle Version
而針對於Android,使用Gradle還須要一款特殊的插件支持,這款插件就是Android Gradle Plugin,你能夠簡單地將其理解爲這是Android和Gradle之間的一個橋樑,這個插件的版本就是所謂的Android Plugin Version
查看方式以下圖所示(這個是更改之後的)
我以前用的三個版本是27,之因此更新爲28,是由於我把Gradle版本給升級了,Gradle升級之後告訴我,你如今的Gradle只支持28及以上的版本,因此逼迫我將三個版本更新爲28,緊接着我又不得不把用到的dependency所有更新爲28
這一更新,就出現了上述的問題
其實目前的解決方法也很簡單,就是把版本滾回去,可是須要你有一份備份代碼
下面敘述一下滾回去的方法
這是以前備份的代碼
打開這個文件,能夠用notepad或者notepad++
我這裏能夠看到,以前用的Android Plugin Version是2.3.3
而後打開這個文件夾
一直點進去
打開這個文件
顯然以前的gradle版本是4.4
好了,如今你已經知道了三個version以及兩個gradle版本
回到你的項目裏,先把這裏改回去
而後這裏改一下
固然三個版本以及對應的dependency版本也要修改
而後再加一句話,加的位置見下圖
最後,clean和rebuild便可
it works like a charm