今天開發組長問了這么一個問題,如何實現通過gradle編譯動態設置代碼里的一些值。可能這么說不太明白,下面說依稀具體需求。
開發中有兩個服務器:一個用於測試版本、一個用於線上版本發布,這兩個服務器地址不同。現在想通過在編譯版本的時候,不去手動更改服務器地址,而是編譯測試版本時,代碼中使用的地址就是測試服務地址,編譯線上版本時,使用線上服務地址。如何實現? 實現原理和多渠道打包是一樣的。下面展示代碼:
(1) 在App的AndroidManifest.xml文件中Application節點下添加:
<meta-data android:name="DATA_NAME" android:value="${DATA_NAME_VALUE}" />
(2)在App的build.gradle文件中添加:
defaultConfig {
applicationId "com.gradle.asdemo"
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION_NAME
minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [DATA_NAME_VALUE: "http://www.mamami.com"] //設置默認的值
}
productFlavors {
ol {
manifestPlaceholders = [DATA_NAME_VALUE: "http://www.mamami.com"] //線上服務地址
}
test {
manifestPlaceholders = [DATA_NAME_VALUE: "http://192.168.58.38"] //測試服務地址
}
}
(3) 在代碼中獲取服務地址的值
public static String getAppMetaData(Context context, String meta_name) { try { ApplicationInfo appInfo = context.getPackageManager() .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); return appInfo.metaData.getString(meta_name); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return null; } public static String getHost(Context context) { String hostURL = getAppMetaData(context, "DATA_NAME"); if (hostURL != null) { return hostURL; } return DEFUALT_HOST; }
這樣在編譯時通過選擇不同的Flavor就可以動態改變服務地址。這里說一下,在我們平時開發debug開發編譯獲取到的地址並不是默認值,而是好像在按照Flavor中設置的name的字典順序拿到的。
(4)可能遇到的問題:Error:(74, 13) Attribute meta-data#xxx@value at AndroidManifest.xml:74:13 requires a placeholder substitution but no value for <YOUMI_CHANNEL_VALUE> is provided
解決方案:(兩處取證說明正確)——其實我遇到這個問題不是這個原因,這是意外收獲。后續我會說明我的那種情況造成這個問題的原因
http://www.tuicool.com/articles/BRNfeiU
http://stackoverflow.com/questions/37368124/gradle-manifest-requires-a-placeholder-substitution-error-but-manifestplacehol
(5)拓展:
使用manifestPlaceholders的這種配置,同樣適用於manifest的其他配置。比如你需要在不同渠道發布的apk里面,指定不同的啟動Activity。比如在豌豆莢里面發布的,啟動的Activity顯示的是豌豆莢首發的界面,應用寶里面啟動的是應用寶首發的界面,你就可以對你的activity的值使用${activity_name}的方式,然后在productFlavors里面配置這個${activity_name}的值。
(6)參考:
http://blog.csdn.net/mynameishuangshuai/article/details/51783303
http://blog.csdn.net/maosidiaoxian/article/details/42000913