http://blog.csdn.net/javazejian/article/details/50757532
通過上一篇gradle多渠道打包的介紹后,本篇我們就來介紹一下多版本apk的打包。在項目的開發(fā)過程,有可能我們會有需要打包多種版本apk的需求,比如當(dāng)測試部門在測試需要我們提供兩種當(dāng)前正在開發(fā)的apk的版本,而且這兩種版本都必須安裝在同一臺手機上,這時我們就需要在打包時打出兩種不同包名的apk去滿足能在同一臺手機上安裝;再比如我們開發(fā)的apk需要在不同的平臺上運行,什么意思?假如我們的apk集成了百度地圖,而百度地圖提供的sdk中含有的so包會提供2種類型的平臺,arm,x86等,這時我們需要根據(jù)不同平臺打出2種類型的apk;還有的時候不同的版本apk中使用到的不同的服務(wù)端api域名也不相同。 比如 beta_api.com,release_api.com等等.......當(dāng)這些情況出現(xiàn)時,我們就需要使用到多版本apk打包啦。當(dāng)然我們不可能每次都手動去更改,這樣的人力成本太高,也無法忍受,這時就需要gradle為我們排憂解難了。
????????在本篇中,我們主要介紹兩種方法也就是多版本apk安裝在同一手機上和集成第3方sdk需要提供多版本apk的情況。
1.多版本apk安裝在同一手機上
????????這種情況只需要我們提供不同包名的apk即可完成。因為只要應(yīng)用包名不一樣即使簽名信息一樣還是可以同時安裝在同一臺手機上的,因此我們應(yīng)該在打包成apk時修改應(yīng)用的包名就可以達(dá)到目的啦。接下來我們進入實際操作過程。這里我們先介紹一個知識點,請直接看下圖:
當(dāng)然從截圖也可以看出,配置多apk打包和上一篇文章配置多渠道打包是一樣的,都是在productFlavors中配置的。如上圖,我們在productFlavors中配置了兩種flavor的apk信息一種是Beta版,一種是Releases版,同時每個flavor中我們都重新配置applicationId這個屬性,通過這個屬性我們就可以使打包出來的apk包名產(chǎn)生對應(yīng)的變化啦。至于為什么重新配置了applicationId就行呢,原因圖已經(jīng)說明啦,就是因為defaultConfig是Beta版和Releases版flavor的基礎(chǔ)配置,只要我們重寫了applicationId這個屬性就會覆蓋defaultConfig中相對應(yīng)屬性的信息,從而使打包出來的兩種apk的包名不一樣,達(dá)到在同一臺手機上安裝的目的。那么applicationId又是什么呢?看下圖(因此我們更改其實就是package屬性)
這里還有點要說明的就是為了在java代碼中可以方便獲取到gradle配置文件的數(shù)據(jù),我們可以通過以下在gradle文件中配置,在java 代碼中使用方式為:context.getResources().getString(R.string.strKey);
當(dāng)然還有可能會有別的需求,比如說不同版本要使用不同的icon,這時該如何做呢?實際上還是在productFlavors的每個flavor中通過manifestPlaceholders屬性配置即可,還是記得我們在上一篇文章說過manifestPlaceholders是一個類似HashMap的容器,因此在manifestPlaceholders可以配置多個屬性,以便在AndroidManifest.xm中使用,比如我們需要為每種版本的apk替換特定的icon和appName這時我們可以這樣如下配置:
然后在AndroidManifest.xm中這樣使用即可:
這樣我們在打包apk時就可以根據(jù)特定需求獲取到不同版本的apk啦,當(dāng)然也可以把渠道配置上去哈,配置方式同上。這里我們給出完整的gradle文件:
[html]
apply?plugin:?'com.android.application'??
android?{??
????signingConfigs?{??
????????debug4zj?{??
????????????keyAlias?'debug4zj'??
????????????keyPassword?'debug4zj'??
????????????storeFile?file('/Users/zejian/Documents/android-studio-workplace/debug4zj.jks')??
????????????storePassword?'debug4zj'??
????????}??
????}??
????compileSdkVersion?23??
????buildToolsVersion?"23.0.2"??
????defaultConfig?{??
????????applicationId?"com.zejian.multi_versionapk"??
????????minSdkVersion?10??
????????targetSdkVersion?23??
????????versionCode?1??
????????versionName?"1.0"??
????}??
????buildTypes?{??
????????release?{??
????????????proguardFiles?getDefaultProguardFile('proguard-android.txt'),?'proguard-rules.pro'??
????????????signingConfig?signingConfigs.debug4zj??
????????????minifyEnabled?true??
????????????zipAlignEnabled?true??
????????}??
????}??
????//配置多版本的apk??
????productFlavors{??
????????Beta{??
????????????applicationId?"com.zejian.multi_versionapk.beta"??
????????????manifestPlaceholders?=?[app_name:"multi_versionapk.beta"?,icon:?"@mipmap/ic_launcher_beta"]??
????????????//在java代碼中具體的使用方式為:context.getResources().getString(R.string.strKey);??
????????????resValue("string"?,?"strKey","beta版本")??
????????}??
????????Releases{??
????????????applicationId?"com.zejian.multi_versionapk.release"??
????????????manifestPlaceholders?=?[app_name:"multi_versionapk.release",icon:?"@mipmap/ic_launcher_releases"]??
????????????resValue("string"?,?"strKey","release版本")??
????????}??
????}??
}??
dependencies?{??
????compile?fileTree(include:?['*.jar'],?dir:?'libs')??
????testCompile?'junit:junit:4.12'??
????compile?'com.android.support:appcompat-v7:23.2.0'??
}??
apply plugin: 'com.android.application' android { signingConfigs { debug4zj { keyAlias 'debug4zj' keyPassword 'debug4zj' storeFile file('/Users/zejian/Documents/android-studio-workplace/debug4zj.jks') storePassword 'debug4zj' } } compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "com.zejian.multi_versionapk" minSdkVersion 10 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.debug4zj minifyEnabled true zipAlignEnabled true } } //配置多版本的apk productFlavors{ Beta{ applicationId "com.zejian.multi_versionapk.beta" manifestPlaceholders = [app_name:"multi_versionapk.beta" ,icon: "@mipmap/ic_launcher_beta"] //在java代碼中具體的使用方式為:context.getResources().getString(R.string.strKey); resValue("string" , "strKey","beta版本") } Releases{ applicationId "com.zejian.multi_versionapk.release" manifestPlaceholders = [app_name:"multi_versionapk.release",icon: "@mipmap/ic_launcher_releases"] resValue("string" , "strKey","release版本") } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.2.0' }
接下來在命令行輸入 ./gradlew assembleRelease,回車,開始打包,打包結(jié)果如下:
現(xiàn)在我們把兩個版本apk都安裝在同一臺手機上試試:
很顯然成功了,然后我們在反編譯一下apk,查看一下AndroidManifest.xml文件,主要觀察一下包名是否發(fā)生變化了,結(jié)果如下:
到此多版本apk安裝同一手機測試成功,告一段落,接下來繼續(xù)研究一下不同平臺的多版本apk。
2.多平臺多版本apk
????????通過上面的分析,這個就顯得比較簡單了,首先我們以百度地圖為例,導(dǎo)入百度地圖的so包,這里僅做演示,不真正集成百度地圖哈。
接下來我們要打2種版本的包,分別是arm平臺,x86平臺,下面我們直接在gradle中配置:
這里一定要注意so包文件夾名稱一定要對應(yīng)!還有這里使用的老版的ndk配置方式,as好像不通過,因我對ndk還沒太多研究,而且這里我們主要是講解apk的打包過程,所以還是決定使用老式配置,不過我們需要在gradle.properties文件中配置一句話,那就是android.useDeprecateNdk=true,即允許使用過時的ndk配置,這樣才能編譯通過哈。接下來就直接運行打包吧,./gradlew assembleRelease,回車運行,把打包好的apk修改后綴為zip,并解壓,查看lib目錄是否分類了so文件即可:
很明顯也成功了吧,到此多平臺多apk打包也就完成啦。本篇也完結(jié)了哈。獻上gradle文件內(nèi)容: