英文原文:Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion
轉(zhuǎn)載原文:https://chinagdg.org/2016/01/picking-your-compilesdkversion-minsdkversion-targetsdkversion/
相關(guān)閱讀:
如何選擇compileSdkVersion, minSdkVersion 和 targetSdkVersion
作者:Ian Lake,Google Android 推廣工程師;翻譯:韓國(guó)愷。
當(dāng)你發(fā)布一個(gè)應(yīng)用之后,(取決于具體的發(fā)布時(shí)間)可能沒(méi)過(guò)幾個(gè)月 Android 系統(tǒng)就發(fā)布了一個(gè)新版本。這對(duì)你的應(yīng)用意味著什么,所有東西都不能用了?
別擔(dān)心,向前兼容是 Android 非常關(guān)注的事情。用戶在升級(jí)到新版 Android 的時(shí)候,用以前版本的 SDK 構(gòu)建的現(xiàn)有應(yīng)用應(yīng)該不會(huì)出問(wèn)題。這就是 compileSdkVersion, minSdkVersion 和 targetSdkVersion 的作用:他們分別控制可以使用哪些 API ,要求的 API 級(jí)別是什么,以及應(yīng)用的兼容模式。
compileSdkVersion
compileSdkVersion 告訴 Gradle 用哪個(gè) Android SDK 版本編譯你的應(yīng)用。使用任何新添加的 API 就需要使用對(duì)應(yīng) Level 的 Android SDK。
需要強(qiáng)調(diào)的是修改 compileSdkVersion 不會(huì)改變運(yùn)行時(shí)的行為。當(dāng)你修改了 compileSdkVersion 的時(shí)候,可能會(huì)出現(xiàn)新的編譯警告、編譯錯(cuò)誤,但新的 compileSdkVersion 不會(huì)被包含到 APK 中:它純粹只是在編譯的時(shí)候使用。(你真的應(yīng)該修復(fù)這些警告,他們的出現(xiàn)一定是有原因的)
因此我們強(qiáng)烈推薦總是使用最新的 SDK 進(jìn)行編譯。在現(xiàn)有代碼上使用新的編譯檢查可以獲得很多好處,避免新棄用的 API ,并且為使用新的 API 做好準(zhǔn)備。
注意,如果使用 Support Library ,那么使用最新發(fā)布的 Support Library 就需要使用最新的 SDK 編譯。例如,要使用 23.1.1 版本的 Support Library ,compileSdkVersion 就必需至少是 23 (大版本號(hào)要一致?。?。通常,新版的 Support Library 隨著新的系統(tǒng)版本而發(fā)布,它為系統(tǒng)新增加的 API 和新特性提供兼容性支持。
minSdkVersion
如果 compileSdkVersion 設(shè)置為可用的最新 API,那么 minSdkVersion 則是應(yīng)用可以運(yùn)行的最低要求。minSdkVersion 是 Google Play 商店用來(lái)判斷用戶設(shè)備是否可以安裝某個(gè)應(yīng)用的標(biāo)志之一。
在開(kāi)發(fā)時(shí) minSdkVersion 也起到一個(gè)重要角色:lint 默認(rèn)會(huì)在項(xiàng)目中運(yùn)行,它在你使用了高于 minSdkVersion 的 API 時(shí)會(huì)警告你,幫你避免調(diào)用不存在的 API 的運(yùn)行時(shí)問(wèn)題。如果只在較高版本的系統(tǒng)上才使用某些 API,通常使用運(yùn)行時(shí)檢查系統(tǒng)版本的方式解決。
請(qǐng)記住,你所使用的庫(kù),如 Support Library 或 Google Play services,可能有他們自己的 minSdkVersion 。你的應(yīng)用設(shè)置的 minSdkVersion 必需大于等于這些庫(kù)的 minSdkVersion 。例如有三個(gè)庫(kù),它們的 minSdkVersion 分別是 4, 7 和 9 ,那么你的 minSdkVersion 必需至少是 9 才能使用它們。在少數(shù)情況下,你仍然想用一個(gè)比你應(yīng)用的 minSdkVersion 還高的庫(kù)(處理所有的邊緣情況,確保它只在較新的平臺(tái)上使用),你可以使用 tools:overrideLibrary 標(biāo)記,但請(qǐng)做徹底的測(cè)試!
當(dāng)你決定使用什么 minSdkVersion 時(shí)候,你應(yīng)該參考當(dāng)前的 Android 分布統(tǒng)計(jì),它顯示了最近 7 天所有訪問(wèn) Google Play 的設(shè)備信息。他們就是你把應(yīng)用發(fā)布到 Google Play 時(shí)的潛在用戶。最終這是一個(gè)商業(yè)決策問(wèn)題,取決于為了支持額外 3% 的設(shè)備,確保最佳體驗(yàn)而付出的開(kāi)發(fā)和測(cè)試成本是否值得。
當(dāng)然,如果某個(gè)新的 API 是你整個(gè)應(yīng)用的關(guān)鍵,那么確定 minSdkVersion 的值就比較容易了。不過(guò)要記得 14 億設(shè)備中的 0.7% 也是個(gè)不小的數(shù)字。
targetSdkVersion
三個(gè)版本號(hào)中最有趣的就是 targetSdkVersion 了。 targetSdkVersion 是 Android 提供向前兼容的主要依據(jù),在應(yīng)用的 targetSdkVersion 沒(méi)有更新之前系統(tǒng)不會(huì)應(yīng)用最新的行為變化。這允許你在適應(yīng)新的行為變化之前就可以使用新的 API (因?yàn)槟阋呀?jīng)更新了 compileSdkVersion 不是嗎?)。
targetSdkVersion 所暗示的許多行為變化都記錄在 VERSION_CODES 文檔中了,但是所有恐怖的細(xì)節(jié)也都列在每次發(fā)布的平臺(tái)亮點(diǎn)中了,在這個(gè) API Level 表中可以方便地找到相應(yīng)的鏈接。
例如,Android 6.0 變化文檔中談了 target 為 API 23 時(shí)會(huì)如何把你的應(yīng)用轉(zhuǎn)換到運(yùn)行時(shí)權(quán)限模型上,Android 4.4 行為變化闡述了 target 為 API 19 及以上時(shí)使用 set() 和 setRepeating() 設(shè)置 alarm 會(huì)有怎樣的行為變化。
由于某些行為的變化對(duì)用戶是非常明顯的(棄用的 menu 按鈕,運(yùn)行時(shí)權(quán)限等),所以將 target 更新為最新的 SDK 是所有應(yīng)用都應(yīng)該優(yōu)先處理的事情。但這不意味著你一定要使用所有新引入的功能,也不意味著你可以不做任何測(cè)試就盲目地更新 targetSdkVersion ,請(qǐng)一定在更新 targetSdkVersion 之前做測(cè)試!你的用戶會(huì)感謝你的。
Gradle 和 SDK 版本
所以設(shè)置正確的 compileSdkVersion, minSdkVersion 和 targetSdkVersion 很重要。如你所想, Gradle 和 Android Studio 都在構(gòu)建系統(tǒng)中集成了它們。在你的模塊的 build.gradle 文件中(也可以在 Android Studio 的項(xiàng)目結(jié)構(gòu)選項(xiàng)中)設(shè)置:
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.checkyourtargetsdk"
minSdkVersion 7
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
}
編譯時(shí)用到的 compileSdkVersion 是和構(gòu)建工具版本一起設(shè)置的 Android 設(shè)置之一。其他兩個(gè)稍有不同,他們?cè)跇?gòu)建變體(build variant)的那里聲明。defaultConfig 是所有構(gòu)建變體的基礎(chǔ),也是設(shè)置這些默認(rèn)值的地方。你可以想象在一個(gè)更復(fù)雜的系統(tǒng)中,應(yīng)用的某些版本可能會(huì)有不同的 minSdkVersion 。
minSdkVersion 和 targetSdkVersion 與 compileSdkVersion 的另一個(gè)不同之處是它們會(huì)被包含進(jìn)最終的 APK 文件中,如果你查看生成的 AndroidManifest.xml 文件,你會(huì)看到類似下面這樣的標(biāo)簽:
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="7" />
如果你在 manifest 文件中手工設(shè)置,你會(huì)發(fā)現(xiàn) Gradle 在構(gòu)建時(shí)會(huì)忽略它們(盡管其它構(gòu)建系統(tǒng)可能會(huì)明確依賴它們)。
綜合來(lái)看
如果你按照上面示例那樣配置,你會(huì)發(fā)現(xiàn)這三個(gè)值的關(guān)系是:
minSdkVersion <= targetSdkVersion <= compileSdkVersion
這種直覺(jué)是合理的,如果 compileSdkVersion 是你的最大值,minSdkVersion 是最小值,那么最大值必需至少和最小值一樣大且 target 必需在二者之間。
理想上,在穩(wěn)定狀態(tài)下三者的關(guān)系應(yīng)該更像這樣:
minSdkVersion (lowest possible) <= targetSdkVersion == compileSdkVersion (latest SDK)
用較低的 minSdkVersion 來(lái)覆蓋最大的人群,用最新的 SDK 設(shè)置 target 和 compile 來(lái)獲得最好的外觀和行為。