使用AndroidStudio的過(guò)程中,對(duì)build.gradle文件配置以及導(dǎo)入支持包的問(wèn)題的一些總結(jié),在此記錄下來(lái)。有時(shí)候,頭疼的不是面對(duì)新功能無(wú)從下手,而是為了可以正常敲代碼與編譯環(huán)境作斗爭(zhēng)。
關(guān)于build.gradle配置
-
compileSdkVersion
SDK的版本號(hào),也就是API Level,例如API-19、API-20、API-21等等,一般保持最新即可。
-
buildeToolVersion
構(gòu)建工具的版本,其中包括了打包工具aapt、dx等等,這個(gè)一般與CompileSdkVersion對(duì)應(yīng)。
這個(gè)工具的目錄位于..your_sdk_path/build-tools/XX.XX.XX,這個(gè)版本號(hào)一般是API-LEVEL.0.0。
-
可以用高版本的build-tool去構(gòu)建一個(gè)低版本的sdk工程
例如build-tool的版本為20,去構(gòu)建一個(gè)sdk版本為18的
compileSdkVersion 18、buildToolsVersion "22.0.1"這樣也是OK的。 targetSdkVersion與minSdkVersion與清單文件中配置一樣,含義一樣。
-
android:minSdkVersion
表示APP所兼容的最低API版本,這個(gè)一般是項(xiàng)目初期就定好的,輕易不會(huì)改動(dòng)。
指明應(yīng)用程序運(yùn)行所需的最小APIlevel。如果不指明的話,默認(rèn)是1。也就是說(shuō)該應(yīng)用兼容所有的android版本。我們應(yīng)該總是聲明這個(gè)屬性。如果系統(tǒng)的APIlevel低于android:minSdkVersion設(shè)定的值,那么android系統(tǒng)會(huì)阻止用戶(hù)安裝這個(gè)應(yīng)用。
報(bào)錯(cuò)信息為:INSTALL_FAILED_OLDER_SDK
如果指明了這個(gè)屬性,并且在項(xiàng)目中使用了高于這個(gè)API level的API, 那么會(huì)在編譯時(shí)報(bào)錯(cuò)。 -
android:targetSdkVersion
表示應(yīng)用程序目標(biāo)API Level的一個(gè)整數(shù),一般設(shè)置成最高的API版本。如果不設(shè)置,默認(rèn)值和minSdkVersion相同。
這個(gè)屬性通知系統(tǒng),你已經(jīng)針對(duì)這個(gè)指定的目標(biāo)版本測(cè)試過(guò)你的程序,系統(tǒng)不必再使用兼容模式來(lái)讓你的應(yīng)用程序向前兼容這個(gè)目標(biāo)版本。應(yīng)用程序仍然能在低于targetSdkVersion的系統(tǒng)上運(yùn)行。
為了讓?xiě)?yīng)用程序支持每個(gè)Android版本,應(yīng)當(dāng)提高targetSdkVersion的值到最新的APIlevel,然后在對(duì)應(yīng)的平臺(tái)上徹底的測(cè)試你的應(yīng)用。可知,targetSdkVersion這個(gè)屬性是在程序運(yùn)行時(shí)期起作用的,系統(tǒng)根據(jù)這個(gè)屬性決定要不要以兼容模式運(yùn)行這個(gè)程序。一般情況下,應(yīng)該將這個(gè)屬性的值設(shè)置為最新的API level 值,這樣的話可以利用新版本系統(tǒng)上的新特性。
關(guān)于v4、v7的導(dǎo)入
假如項(xiàng)目是APPModule,需要依賴(lài)另外兩個(gè)Module,A和B。但是ModuleA和ModuleB都需要導(dǎo)入V4包,各自在相應(yīng)的gradle文件中compile v4即可,不過(guò)最好版本保持一致,這樣是沒(méi)問(wèn)題的。假如此時(shí)APP Module需要v4包,就不必引入v4了,因?yàn)樵谝蕾?lài)ModuleA和ModuleB的時(shí)候,已經(jīng)也依賴(lài)了v4包。假如此時(shí)APP Module需要v7包,只需要在APP Module的gradle里面compile v7包就可以了,這樣并不會(huì)沖突。
v7里面包含了v4的所有內(nèi)容,所以如果導(dǎo)入了v7,就不用再導(dǎo)入v4。
如果原來(lái)項(xiàng)目中引入的v7版本是19,后來(lái)想升級(jí)到23,直接改相應(yīng)的數(shù)字就可以,但是這個(gè)版本要存在。同時(shí),要修改相應(yīng)的compileSdkVersion、buildeToolVersion、targetSdkVersion版本號(hào),保持一致,不然會(huì)出現(xiàn)
Process 'command 'd:\Program\Android\sdk\build-tools\23.0.3\aapt.exe'' finished with non-zero exit value 1這種錯(cuò)誤。
錯(cuò)誤類(lèi)型
-
aapt.exe'' finished with non-zero exit value 1
這種錯(cuò)誤一般是由compileSdkVersion、buildeToolVersion、targetSdkVersion這種版本號(hào)與v4或v7的版本號(hào)不一致導(dǎo)致的,修復(fù)的方法就是修改這些數(shù)字,使版本號(hào)一致。當(dāng)項(xiàng)目中存在多個(gè)Module的時(shí)候,最好將compileSdkVersion、buildeToolVersion、targetSdkVersion等配置成一樣的,防止出現(xiàn)莫名其妙的問(wèn)題。
-
Multiple dex files define XXXXandroid/support/v4/aXXXX
這種錯(cuò)誤,一定是v4或v7包重復(fù)引用導(dǎo)致的,除了要看build.gradle文件的compile的支持包以外,還要看libs文件夾下是不是也有了這些支持包。相應(yīng)的,如果報(bào)錯(cuò)信息Multiple dex files define是這種開(kāi)頭的,一定是導(dǎo)包重復(fù)造成的,有可能重復(fù)導(dǎo)入了其他的第三方,具體是哪個(gè)重復(fù),從報(bào)錯(cuò)信息里應(yīng)該能看出來(lái)。
-
Error: No resource found that matches the given name: attr XXXXXX
這種錯(cuò)誤一定是compileSdkVersion、buildeToolVersion、targetSdkVersion這種版本號(hào)與v4或v7的版本號(hào)不一致導(dǎo)致的,修復(fù)的方法就是修改這些數(shù)字,使版本號(hào)一致。比如原來(lái)是引用的v4的19.0.0版本,后來(lái)改成23.1.1,但是targetSdkVersion卻還是原來(lái)的19,這樣編譯的時(shí)候,編譯的時(shí)候使用的是v4的23.1.1版本,但是找資源的時(shí)候,還是找的v4的19.0.0版本的,就會(huì)找不到。
-
Attribute has already been defined XXXXXXXXXXXX
這種錯(cuò)誤一是重復(fù)導(dǎo)包導(dǎo)致,二是自定義的屬性與系統(tǒng)中(一般是支持包中)的屬性名字重復(fù)。如果確定沒(méi)有重復(fù)導(dǎo)包,就復(fù)制那個(gè)重復(fù)的屬性名字,Android Studio中按Ctrl + H組合鍵,全局搜索,肯定可以找到自己定義的那個(gè)屬性。不要覺(jué)得自己根本沒(méi)有定義過(guò)這個(gè)屬性,因?yàn)橛锌赡茼?xiàng)目的其他成員定義過(guò),或者自己忘了,都有可能發(fā)生,利用工具,相信工具。一般是在attr.xml這個(gè)文件中。
-
com.android.dex.DexIndexOverflowException: Cannot merge new index XXXXXX into a non-jumbo instruction!(這個(gè)XXX數(shù)字一定大于65536)
以及com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536”錯(cuò)誤原因:
這個(gè)錯(cuò)誤可能在導(dǎo)入第三方的時(shí)候會(huì)出現(xiàn)。
原因是同時(shí)在工程中引入了多個(gè)第三方j(luò)ar包,導(dǎo)致調(diào)用的方法數(shù)超過(guò)了android設(shè)定的65536個(gè)(DEX 64K problem),進(jìn)而導(dǎo)致dex無(wú)法生成,也就無(wú)法生成APK文件。
限制原因:早期的Dalvik VM內(nèi)部使用short類(lèi)型變量來(lái)標(biāo)識(shí)方法的id,就有了 最大方法數(shù)的限制65536。
解決辦法有兩種:第一種是忽略方法數(shù)限制的檢查
這樣做的缺點(diǎn)是apk無(wú)法再低版本的設(shè)備上面安裝,會(huì)出現(xiàn)錯(cuò)誤:
INSTALL_FAILED_DEXOPT
在App Module的build.gradle文件的android節(jié)點(diǎn)下添加如下代碼:dexOptions { jumboMode = true }第二種是分包
通過(guò)在defaultConfig中設(shè)置multiDexEnabled可以開(kāi)啟分包模式,分包之后的Dex就低于了限制數(shù),保證了正常的打包。
defaultConfig {
multiDexEnabled=true
}
//這時(shí)還要
compile 'com.google.android:multidex:0.1' 0.1是版本號(hào),用最新的就行。
-
程序包org.apache.http 、org.apache.http.client.utils等不存在
解決:在build.gradle(Module:app) 文件的android的那個(gè)括號(hào)里加上
useLibrary 'org.apache.http.legacy'
參考
- 關(guān)于dexOptions
- 解決Android方法數(shù)超出限定的問(wèn)題
- Android 使用android-support-multidex解決Dex超出方法數(shù)的限制問(wèn)題
總結(jié)
在項(xiàng)目中,對(duì)于第三方的SDK或者jar等,可以在build.gradle中compile的就compile,不要導(dǎo)入Module,再compile project,容易出問(wèn)題。
導(dǎo)入第三方的時(shí)候,一定要仔細(xì)參考官方文檔集成說(shuō)明或者官方demo。
遇到這些問(wèn)題的時(shí)候,誰(shuí)都會(huì)頭大,就這些問(wèn)題,折騰了我一個(gè)多星期,慢慢熬,去google上多看看別人的相同或相似問(wèn)題,看看大神們的解答,最好明白其中的道理,記錄下來(lái),看多了有時(shí)候說(shuō)不定就突然把問(wèn)題解決了。