前言:
今天項目集成了極光推送,但是極光推送沒有沙箱環(huán)境,線上生產(chǎn)環(huán)境又不能進(jìn)行測試讳推,所以需要專門打包一個debug的版本,用于測試玩般;還有:在用到一個第三方sdk银觅,但是這個sdk并沒有區(qū)分開發(fā)環(huán)境和線上環(huán)境,這時候我們就可能會申請兩個不同的key標(biāo)識坏为,而且很多key標(biāo)識都只能在androidmanifest里面配置究驴。所以每次上線生成apk就必須手動去更改key標(biāo)識,如果渠道版本少也還好匀伏,打包速度快也還行洒忧,需要區(qū)分環(huán)境的的key標(biāo)識相對較少也還不錯 ,但是如果你一項都沾不到邊够颠,到時忘記哪個key忘記替換了熙侍,那后期就會很麻煩;
- 先在androidmanifest文件配置一個節(jié)點(diǎn)履磨,這里以極光為例
<meta-data
android:name="JPUSH_APPKEY"
android:value="${JPUSH_APPKEY_VALUE}" /> <!-- <!– 如果引入了one-push-umeng類庫 –> -->
build.gradle寫法
buildTypes {
release {
signingConfig signingConfigs.release
// 如果沒有提供混淆規(guī)則文件蛉抓,則設(shè)置默認(rèn)的混淆規(guī)則文件(SDK/tools/proguard/proguard-android.txt)
pseudoLocalesEnabled false
// 不顯示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//Zipalign優(yōu)化
zipAlignEnabled true
// 移除無用的resource文件
shrinkResources true
//是否Debug
debuggable false
// minifyEnabled true relase 為true
//是否混淆
minifyEnabled true
//加載默認(rèn)混淆配置文件
proguardFile 'C:/workSpace/project/patient/proguard-rules.pro'
manifestPlaceholders = [JPUSH_APPKEY_VALUE: "......108f7c76dd",
APP_NAME:"@string/app_name"
]
}
debug {
signingConfig signingConfigs.debug
// 如果沒有提供混淆規(guī)則文件,則設(shè)置默認(rèn)的混淆規(guī)則文件(SDK/tools/proguard/proguard-android.txt)
pseudoLocalesEnabled false//是否在APK中生成偽語言環(huán)境剃诅,幫助國際化的東西巷送,一般使用
// 不顯示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//Zipalign優(yōu)化
zipAlignEnabled false
// 移除無用的resource文件
shrinkResources false
//是否開啟debug
debuggable true
// minifyEnabled true
//加載默認(rèn)混淆配置文件
minifyEnabled false
//proguardFile 'C:/workSpace/project/patient/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationIdSuffix ".debug"
manifestPlaceholders = [JPUSH_APPKEY_VALUE: "..........49377a7",
APP_NAME:"@string/app_name_debug"
]
}
}
在bulidtypes節(jié)點(diǎn)下有release節(jié)點(diǎn)和debug節(jié)點(diǎn),正式簽名時就會走release節(jié)點(diǎn)的下編譯腳本综苔,調(diào)試簽名時就會走debug節(jié)點(diǎn)惩系。
本文主要點(diǎn)就是紅框標(biāo)記的manifestPlaceholders的用法,jpush_appkey對應(yīng)的就是之前在androidmanifest文件配置的${jpush_appkey}的這個值如筛。
其實就是一個HashMap的對象堡牡,我們在build.gradle中寫入,然后映射到AndroidMainfest.xml中杨刨,HashMap對象放置在activityInfo.metaData中晤柄,我們可以通過activityInfo.metaData.keyset()查看所有設(shè)置的值
我們在程序入口出打上log,用來檢驗key的值妖胀,可以直接寫在application中
String jpush_appkey;
try {
ApplicationInfo appInfo = getPackageManager()
.getApplicationInfo(getPackageName(),
PackageManager.GET_META_DATA);
jpush_appkey = appInfo.metaData.getString("JPUSH_APPKEY");
Log.w("jpush_appkey=" , jpush_appkey);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
但是這樣我們還不能生成兩個包芥颈,生成兩個包惠勒,就是必須要包名不一樣才可以,也就是ApplicationID值不一樣
Application ID
每個Android app都有一個唯一的application ID爬坑,就像Java包名一樣纠屋,例如com.example.myapp。 此ID可在設(shè)備和Google Play商店中唯一標(biāo)識您的應(yīng)用盾计。 如果要上傳新版app售担,application ID(以及sign用的證書)必須與舊版本的APK相同,如果您變更application ID署辉,Google Play商店會將APK視為完全不同的 app族铆。 因此,一旦發(fā)布應(yīng)用程序哭尝,您就不應(yīng)更改application ID哥攘。
application ID是使用模塊build.gradle文件中的applicationId屬性定義的,如下所示:
defaultConfig {
applicationId "com.test.com"
minSdkVersion 19
targetSdkVersion 28
versionCode 25
versionName "1.0.6"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
//原因是Android系統(tǒng)定義總方法數(shù)是一個short int材鹦,short int 最大值為65536逝淹。解決這個問題的方案是:
ndk {
//選擇要添加的對應(yīng)cpu類型的.so庫。
abiFilters 'armeabi-v7a'
// 'armeabi'
// ,'x86', 'x86_64', 'mips', 'mips64','armeabi-v8a', 'x86', 'x86_64', 'armeabi-v7a'
}
vectorDrawables.useSupportLibrary = true
signingConfig signingConfigs.release
// multiDexKeepProguard file("./tinker_multidexkeep.pro") //keep specific classes using proguard syntax
}
當(dāng)您在Android Studio中創(chuàng)建新項目時侠姑,applicationId與在setup過程中選擇的the Java-style package name完全匹配创橄。 但是,application ID和包名稱在這一點(diǎn)之外是彼此獨(dú)立的莽红。 你可以更改程序包名稱(代碼命名空間)妥畏,它不會影響application ID,反之亦然(但是安吁,一旦發(fā)布應(yīng)用程序醉蚁,您就不應(yīng)該更改application ID)。 但是鬼店,更改包名稱有一些你應(yīng)該注意的后果网棍,請參閱修改包名稱的部分。
雖然application ID看起來像一個傳統(tǒng)的Java package name妇智,但application ID的命名規(guī)則有一些限制:
- 它必須至少有兩個片段(一個或多個點(diǎn))滥玷。
- 每個片段必須以字母開頭。
- 所有字符必須為字母數(shù)字或下劃線[a-zA-Z0-9_]巍棱。
注意:application ID以前直接綁定到包名稱; 因此一些Android API在其方法名稱和參數(shù)名稱中使用術(shù)語“包名稱”惑畴,但這實際上是application ID。 例如航徙,Context.getPackageName()方法返回application ID如贷。 沒有必要在app代碼之外分享代碼的真實包名。
警告:如果您正在使用WebView,請考慮在application ID中使用您的程序包名稱作為前綴;
更改build variants的application ID
當(dāng)為應(yīng)用程序構(gòu)建APK時杠袱,構(gòu)建工具使用build.gradle文件中的defaultConfig塊中定義的application ID來標(biāo)記APK(如下所示)尚猿。 但是,如果您想要創(chuàng)建不同版本的應(yīng)用以在Google Play商店中顯示為單獨(dú)的商家信息(例如“免費(fèi)”和“專業(yè)版”)楣富,則需要分別創(chuàng)建具有不同application ID的獨(dú)立的build variant凿掂。
在這種情況下,每個build variant應(yīng)定義為單獨(dú)的product flavor菩彬。 對于productFlavors {}塊中的每個flavor缠劝,您可以重新定義applicationId屬性潮梯,或者可以使用applicationIdSuffix將片段添加到默認(rèn)application ID后面骗灶,如下所示:
這樣,“free”product flavor的application ID為“com.example.myapp.free”秉馏。
您還可以使用applicationIdSuffix根據(jù)您的build type附加片段耙旦,如下所示:
因為Gradle在product flavor之后應(yīng)用build type配置,所以“free debug”build variant的application ID現(xiàn)在是“com.example.myapp.free.debug”萝究。 當(dāng)您希望在同一設(shè)備上同時創(chuàng)建debug和release版本時免都,這是非常有用的,因為沒有兩個APK可以具有相同的application ID帆竹。
請注意绕娘,具有不同application ID的APK會被視為Google Play商店中不同的app。 因此栽连,如果您想使用相同的app清單來分發(fā)多個APK险领,而每個APK都指定不同的device configuration(例如API等級),則必須為每個build variant使用相同的application ID秒紧,但是為每個APK提供不同的versionCode绢陌。 有關(guān)詳細(xì)信息,請閱讀有關(guān)Multiple APK支持熔恢。
警告:為了與以前的SDK tools兼容脐湾,如果未在build.gradle文件中定義applicationId屬性,build tools將使用AndroidManifest.xml文件中的包名稱作為application ID叙淌。 在這種情況下秤掌,重構(gòu)包名稱也會更改application ID。
提示:如果您需要在manifest file中引用應(yīng)用程序ID鹰霍,則可以在任何manifest attribute中使用$ {applicationId}占位符闻鉴。 在構(gòu)建期間,Gradle將此標(biāo)記重新放置為實際application ID衅谷。 有關(guān)更多信息椒拗,請參閱將Build Variables注入到Manifest。
更改application ID以進(jìn)行測試
默認(rèn)情況下,build tools會使用指定build variant的application ID應(yīng)用到您的instrumentation測試APK, 附加.test蚀苛。 例如在验,com.example.myapp.free build variant的測試APK的application ID為com.example.myapp.free.test。
雖然沒有必要堵未,但您可以通過在defaultConfig或productFlavor塊中定義testApplicationId屬性來更改 application ID腋舌。
注意:為了避免與測試中的app發(fā)生名稱沖突碰煌,build tools會為測試APK生成R類钱烟,并使用基于test application ID的命名空間,而不是manifest file中定義的包名稱朴沿。
更改包名稱
雖然默認(rèn)情況下項目的程序包名稱與application ID相匹配雌芽,但你可以更改它授艰。 但是,如果要更改程序包名稱世落,請注意程序包名稱(由項目目錄結(jié)構(gòu)定義)應(yīng)始終與AndroidManifest.xml文件中的package attribute相匹配淮腾,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp"
android:versionCode="1"
android:versionName="1.0" >
Android build tools使用package attribute來做兩件事情:
- 它將此名稱應(yīng)用為應(yīng)用程序生成的R.java類的命名空間。
示例:使用上面的manifest屉佳,R類將是com.example.myapp.R谷朝。 - 它使用它來解析在manifest file中聲明的任何相關(guān)類名。
示例:使用上面的manifest武花,聲明為<activity android:name =“.MainActivity”>的activity被解析為com.example.myapp.MainActivity圆凰。
因此,package attribute中的名稱應(yīng)該始終與項目的activities和app代碼中的基本包名稱匹配体箕。 當(dāng)然专钉,你可以在項目中有子包,但是這些文件必須使用package attribute中的命名空間導(dǎo)入R.java類干旁,并且manifest中聲明的任何應(yīng)用程序組件必須添加缺少的子包名稱(或者使用完整包名稱)驶沼。
如果你想完全重構(gòu)你的包名,一定要更新package attribute争群。 只要您使用Android Studio's tools 重命名和重構(gòu)您的軟件包回怜,則這些就會自動保持同步。 (如果它們不保持同步换薄,您的應(yīng)用代碼無法解析R類玉雾,因為它不在同一個包中,而且manifest將無法識別activities或其他組件轻要。)
您必須始終在項目的主AndroidManifest.xml文件中指定package attribute复旬。 如果您有其他清單文件(例如對于product flavor 或者 build type),請注意冲泥,由最高優(yōu)先級manifest file提供的軟件包名稱始終用于最終合并的manifest驹碍。 有關(guān)更多信息壁涎,請參閱合并多個清單文件。
還有一件事要知道:雖然manifest包名稱和Gradle applicationId可能有不同的名稱志秃,但build tools會在構(gòu)建結(jié)束時將application ID復(fù)制到APK的最終manifest file中怔球。 所以如果你在構(gòu)建之后檢查你的AndroidManifest.xml文件,不要驚訝包屬性已經(jīng)改變浮还。 package attribute是Google Play商店和Android平臺實際用來識別app的地方竟坛。
需要到谷歌的開發(fā)中心閱讀文檔,自己想辦法