如何利用同一套代码,要打包不同applicationId,不同图标,不同包名,不同启动页等?此时就需要用到构建神器-gradle。
先上代码
...
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "com.edt.edtdoctor"
minSdkVersion 16
targetSdkVersion 23
versionCode 124
versionName "1.2.4"
ndk {
abiFilters "armeabi"/*, "x86"*/
}
buildConfigField("String", "CHAT_DIRECTION", '"1"')
buildConfigField("String", "XF_APPID", '"***"')
buildConfigField("String", "CLIENT_ID", '"doctor"')
buildConfigField("String", "WECHAT_KEY_VALUE", '"***"')
//Enabling multidex support
multiDexEnabled true
}
tasks.whenTaskAdded { task ->
if (task.name.contains("lint")
//如果instant run不生效,把clean这行干掉
//||task.name.equals("clean")
//如果项目中有用到aidl则不可以舍弃这个任务
||task.name.contains("Aidl")
//用不到测试的时候就可以先关闭
||task.name.contains("mockableAndroidJar")
||task.name.contains("UnitTest")
||task.name.contains("AndroidTest")
//用不到NDK和JNI的也关闭掉
//|| task.name.contains("Ndk")
//|| task.name.contains("Jni")
) {
task.enabled = false
}
}
signingConfigs {
release {
try {
storeFile file('./keystore/edt_edtdoctor.jks')
keyAlias 'china'
keyPassword '******'
storePassword '******'
} catch (ex) {
throw new InvalidUserDataException(ex.toString())
}
}
debug {
storeFile file("./keystore/debug.keystore")
}
}
//友盟统计不同渠道(具体值看androidManifest.xml)
productFlavors {
huawei {
applicationId "com.edt.***"
buildConfigField("boolean", "IS_DEVELOP", "false")
resValue "string", "app_name", "appName"
buildConfigField("String", "BUGLY_ID", '"***"')
manifestPlaceholders = [JPUSH_APPKEY_VALUE : "***",
EASEMOB_APPKEY_VALUE: "***",
UMENG_APPKEY_VALUE : "***",
UMENG_CHANNEL_VALUE : "huawei",
START_BACKGROUND : "@style/Splash_Theme",
app_icon : "@mipmap/ic_launcher"]
}
develop {
applicationId "com.edt.***"
buildConfigField("boolean", "IS_DEVELOP", "true")
resValue "string", "app_name", "another"
buildConfigField("String", "BUGLY_ID", '"***"')
manifestPlaceholders = [JPUSH_APPKEY_VALUE : "***",
EASEMOB_APPKEY_VALUE: "***",
UMENG_APPKEY_VALUE : "***",
UMENG_CHANNEL_VALUE : "develop",
START_BACKGROUND : "@style/Three_Splash_Theme",
app_icon : "@drawable/icon"]
}
// productFlavors.all { flavor ->
// //UMENG_CHANNEL_VALUE即为AndroidManifest.xml中的具体值,此值代表统计渠道
// flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
// }
}
lintOptions {
tasks.lint.enabled = false
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
configurations.all {
resolutionStrategy.force 'com.android.support:support-annotations:23.0.1'
}
buildTypes {
debug {
manifestPlaceholders = [JPUSH_APPKEY_VALUE : "***",
EASEMOB_APPKEY_VALUE: "***",
UMENG_APPKEY_VALUE: "***",
START_BACKGROUND : "@style/Splash_Theme",
app_icon: "@mipmap/ic_launcher"]
buildConfigField("String", "BUGLY_ID", '"***"')
signingConfig signingConfigs.release
}
release {//正式发布的时候使用
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
// 批量打包
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
//输出apk名称为:渠道名_版本名_时间.apk
def fileName = "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${releaseTime()}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}
aaptOptions {
additionalParameters "--no-version-vectors"
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
...
其中需要关注的是三部分:
defaultConfig {},buildTypes {},productFlavors {}
这三部分均可以对applicationId,图标及appname进行设置,但是优先级不同。优先级如下:
buildTypes > productFlavors > defaultConfig
设置AndroidManifest.xml中的属性可以通过manifestPlaceholders 进行设置,不同场景下的常量可以通过buildConfigField进行设置,资源的引用通过resValue 进行设置。
1、在AndroidManifest.xml中
将icon的属性值修改为”${app_icon}”
".core.global.UserApplication"
android:allowBackup="true"
android:icon="${app_icon}"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
......
</application>
2、在app.gradle文件下对”${app_icon}”中的app_icon的值进行设置。如下
manifestPlaceholders = [app_icon: "@mipmap/ic_launcher"]
注意:如果是通用的属性,可以在defaultConfig 中进行设置;不同的属性,通过productFlavors 或者buildTypes (设置debug或者release)进行设置。
3、如果编译是报错,可以加上如下语句:
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
1、注释掉strings.xml中的app_name的资源
<resources>
<string name="ToastError">网络错误,请检查网络后重试string>
<string name="sava_success">保存成功string>
resources>
2、在app.gradle文件下设置app_name的资源
resValue "string", "app_name", "app名称"
1、在AndroidManifest.xml中修改包名为${applicationId}引用,如下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.edt.edtdoctor">
<permission
android:name="${applicationId}.permission.JPUSH_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE"/>
<application
android:name=".core.global.UserApplication"
android:allowBackup="true"
android:icon="${app_icon}"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".section.entry.controller.activity.StartActivity"
android:theme="${START_BACKGROUND}">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
<meta-data
android:name="${applicationId}.GlideModule"
android:value="GlideModule"/>
<meta-data
android:name="UMENG_APPKEY"
android:value="${UMENG_APPKEY_VALUE}"/>
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}"/>
<meta-data
android:name="DOMAIN_PACKAGE_NAME"
android:value="${applicationId}"/>
<meta-data
android:name="EASEMOB_APPKEY"
android:value="${EASEMOB_APPKEY_VALUE}"/>
<meta-data
android:name="JPUSH_CHANNEL"
android:value="developer-default"/>
<meta-data
android:name="JPUSH_APPKEY"
android:value="${JPUSH_APPKEY_VALUE}"/>
application>
2、在app.gradle文件中根据不同的渠道在productFlavors 中进行设置,如下
productFlavors {
huawei {
applicationId "com.edt.***"
}
develop {
applicationId "com.edt.***"
}
做完以上设置以后,通过Build > Generate Signed APK,选择签名后,就可以选择不同的渠道进行打包了。如果想要在debug状态下进行测试,将相关的代码复制一份放到buildTypes的debug{}中即可。
注:如果上面有不当的地方,烦请斧正。
Gradle多渠道打包(动态设定App名称,应用图标,替换常量,更改包名,变更渠道)
Android——Gradle 心得 、变量、 多渠道、一些坑
使用Gradle构建多个不同applicationId包