因爲 android 中以 applicationId
做爲應用惟一標識,因此不能在手機上安裝兩個相同 applicationId
的app。在 AS 中,默認建立的項目其 applicationId
就是項目的包名。能夠在gradle 中配置更改 改 applicationid。android
最近,維護的一個項目是一個導流的,一套代碼每次打包成5個APP。每一個APP除名字、icon、部分資源文件不一樣外,其餘的基本同樣。因爲是維護項目,以前的同事是將其分紅5個項目,那樣每次迭代,都要在一個項目中寫完測試經過後,拷貝到其餘四個項目中,最後一個個項目打包。這樣,既麻煩又浪費時間。所以,打算經過配置 gradle,打包時更換不一樣的 applicationeId、資源文件以及友盟的appkey,從而簡化每次迭代的過程。git
爲了方便測試,這裏將 DifPackage 項目打包爲 one
、two
、three
三個apk, applicationId
分別爲:cn.imtianx.one、cn.imtianx.two 、cn.imtianx.three 。
其中,每一個apk有不一樣的icon、不一樣的名字及界面上顯示的文字也不一樣。github
在 src
下分別創建 one、two、three三個目錄存放對應的資源文件,這裏主要存放 apk icon、資源文件以及兼容7.0拍照用的 provider配置文件。(更多7.0拍照適配,請點擊此處查看)
具體項目結構以下圖所示:安全
說明: 上圖中,one、two、three三個問價夾在 src下,與 main 同級。one 中 res 下的文件目錄和 main/src/res相同。app
對於簽名文件的配置,有兩種方式:一是直接寫 build.gradle
中,而是寫 在 local.properties
文件中。後者想丟安全些,local.properties 一般爲忽略文件不會提交。以下配置:
方法一:在 build.gradle 文件中的 android 下添加以下代碼ide
signingConfigs{ one { storeFile file("E\:\\workspace\\android_temp\\DifPackage\\app\\imtianx_one.jks") storePassword 123456 keyAlias imtianx keyPassword 123456 } /* two,three配置相似 */ }
方法二:首先在 local.properties 下添加密鑰信息,而後在 build.gradle 中讀取使用測試
/*local.properties */ ## one keystore file keystroe_storeFile_1 =E\:\\workspace\\android_temp\\DifPackage\\app\\imtianx_one.jks keystroe_storePassword_1 =123456 keystroe_keyAlias_1 =imtianx keystroe_keyPassword_1 =123456 /* build.gradle */ Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) signingConfigs{ one { storeFile file(properties.getProperty("keystroe_storeFile_1")) storePassword properties.getProperty("keystroe_storePassword_1") keyAlias properties.getProperty("keystroe_keyAlias_1") keyPassword properties.getProperty("keystroe_keyPassword_1") }
以 one 的配置爲例,對於 two和three的配置與此相似。我的一般喜歡第二中配置方式。gradle
因爲不一樣的app使用的友盟統計也不一樣,這裏須要設置佔位符在gradle中進行動態的替換。此外,對於7.0之後的拍照,provider 的配置要與 applicationId 同樣。以下部分代碼:ui
<application> <!-- 友盟統計 appkey--> <meta-data android:name="UMENG_APP_KEY" android:value="${UMENG_APP_KEY_VALUE}"/> <!-- 友盟統計 渠道--> <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"/> <!-- 7.0 camera provider --> <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </provider> </application>
說明:開始兩個 meta中的 value,在 gradle進行設置值,provider 中 的 applicationId 直接能夠取到 gradle中配置的值。加密
這裏主要是利用了多渠道打包的原理,在 productFlavors 中進行配置:
productFlavors{ one{ applicationId "cn.imtianx.one" manifestPlaceholders = [UMENG_APP_KEY_VALUE:"111111",UMENG_CHANNEL_VALUE:"one"] signingConfig signingConfigs.one } two{ applicationId "cn.imtianx.two" manifestPlaceholders = [UMENG_APP_KEY_VALUE:"222222",UMENG_CHANNEL_VALUE:"two"] signingConfig signingConfigs.two } three{ applicationId "cn.imtianx.three" manifestPlaceholders = [UMENG_APP_KEY_VALUE:"333333",UMENG_CHANNEL_VALUE:"three"] signingConfig signingConfigs.three } }
說明:
productFlavors
下的 one、two、three這裏表明三個渠道。applicationId
用於配置應用 id,manifestPlaceholders
用於給 AndroidManifest 中配置的佔位符設置值,這裏僅僅爲了測試隨便寫的值。signingConfig signingConfigs.one
指定不一樣app的簽名文件。此外,指定簽名文件還能夠按照下面的方式:
buildTypes { productFlavors.one.signingConfig signingConfigs.one productFlavors.two.signingConfig signingConfigs.two productFlavors.three.signingConfig signingConfigs.three }
到此整個 配置已經結束。完整 gradle 的配置,請查看 build.gradle
在 terminal 下輸入 gradle assembleRelease
進行打包,而後安裝測試,能夠成功的替換app的icon、名字及其餘資源,可以同時安裝。
若是須要查看 apk的簽名信息,能夠將其解壓後,使用以下命令查看:
keytool -printcert -file META-INF/CERT.RSA
爲了可以區別,前面建立 key store 時儘可能用不一樣的信息。
至此,改打包方式介紹完畢,可是若是用這種方式,則不能進行 多渠道打包,這裏多的 one、two、three相似於三個渠道。
項目源代碼地址:DifPackage