使用Gradle动态配置资源

2017-01-12  本文已影响0人  5e1b18effb55
使用Gradle动态配置资源

关键词:Gradle 多渠道打包 动态更换资源

Eclipse中可以使用Ant动态替换文件中的字符串,或者替换文件实现动态更换项目资源,实现快速打包。
例如:可以实现多渠道打包,debug版与release版访问不同服务器可以动态替换,多个app差异只是 App名字App图标 或者 App访问的服务器不同,这些使用gradle可以更方便的做到,而且gradle不是替换资源,而是配置资源。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "net.ljt.gradledemo"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.0'
    testCompile 'junit:junit:4.12'
}

在默认的基础上添加productFlavors

android {
       ...
    productFlavors{
    }
       ...
}

在productFlavors里面创建不同包的标签

productFlavors {
        xiaomi {}
        baidu {}
        huawei {}
        yingyongbao {}
        _360{}
    }

当然也可以创建其他非应用商店的标签,例如你要打包多个不同名字的apk,那么就用不同的名字作标签

productFlavors {
        xiaomi {}
        baidu {}
        huawei {}
        yingyongbao {}
        _360{}

        gradle{}
        gradledemo{}
    }

在标签中指定需要替换的资源

android {
    ...
    defaultConfig {
        applicationId "net.ljt.gradledemo"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    signingConfigs {    
        xiaomi {        
            keyAlias 'xiaomi'        
            keyPassword 'xiaomi123'
            storeFile file('xiaomi.keystore')
            storePassword 'xiaomi123'
        }
        baidu {
            keyAlias 'baidu'
            keyPassword 'baidu123'
            storeFile file('baidu.keystore')
            storePassword 'baidu123'
        }
    }
    productFlavors {
        xiaomi {
            applicationId "net.ljt.gradle.xiaomi"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 3
            versionName "1.2" 
            signingConfig signingConfigs.xiaomi
        }
        baidu {
            applicationId "net.ljt.gradle.baidu"
            minSdkVersion 15
            targetSdkVersion 24
            versionCode 2
            versionName "1.1"
            signingConfig signingConfigs.baidu
        }
        huawei {}
        yingyongbao {}
        _360{}

        gradle{}
        gradledemo{}
    }
    ...
}

如果你的flavor里面只是替换非常简单的字符串,例如渠道号,就可以简略的这样写

productFlavors {
        xiaomi {}
        baidu {}
        huawei {}
        yingyongbao {}
        _360{}

        gradle{}
        gradledemo{}
    }
    //使用循环遍历所有flavor
    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }

使用manifestPlaceholders指定需要替换的AndroidManifest.xml文件中的资源

xiaomi {
    ...
    manifestPlaceholders = [AMAP_APIKEY         : "4598462156234arh456bsehsd5",
                            UMENG_APPKEY        : "95aerh5h4sr4s65h65f4gha",
                            UMENG_MESSAGE_SECRET: "54FGB4A5B4a45eth45a5FA5s5g45dn"]
}

对应AndroidManifest.xml中使用下面字段代替

${AMAP_APIKEY}
${UMENG_APPKEY}
${UMENG_MESSAGE_SECRET}

替换资源

如果需要替换图片,string.xml文件中的资源,需要在src目录下main文件夹同级目录创建对应标签的文件夹,并且在文件夹下创建对应需要替换内容的文件的目录,对于图片,放置一个同名图片即可,对于string.xml文件,只需要在里面指定需要替换的部分即可

<resources>
    <string name="app_name">GradleDemo</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
</resources>
<resources>
    <string name="app_name">_360</string>
</resources>
项目目录

如果需要替换java文件,同样需要在对应的文件夹下面创建同名的java文件,这时工程会报错,告诉你出现了同名文件,需要把main目录下面的java文件删除掉。

报错 删除后不报错

打包配置(非必要)

先来个默认的

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

再来一个自定义打包的

    buildTypes {
        release {
            // 不显示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            minifyEnabled true
            shrinkResources true //移除无用资源
            debuggable false
            zipAlignEnabled true //zipalign优化
            signingConfig signingConfigs.hxtx
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            // 自定义输出配置
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        //在这里可以自定义打包后的文件名
                        def fileName = "${variant.flavorName}_${variant.versionName}_${releaseTime()}.apk"
                        output.outputFile = new File(outputFile.parent, fileName)
                    }
                }
                //过滤掉unaligned的包
                variant.assemble.doLast {
                    variant.outputs.each { output ->
                        File unaligned = output.packageApplication.outputFile;
                        File aligned = output.outputFile
                        if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {
                            unaligned.delete()
                        }
                    }
                }
            }
        }
    }

这里用到了一个releaseTime()函数,需要在gradle文件中定义这个函数

def releaseTime() {
    return new Date().format("yyyy-MM-dd-HH-mm-ss", TimeZone.getTimeZone("UTC"))
}

打包

使用Android Studio打包签名的apk包

签名打包

我们看到Flavors里面是我们配置过的一些渠道名,这里你可以单选也可以多选,每一个Flavors都对应一个apk包

最后祭出完整版的Gradle文件

apply plugin: 'com.android.application'

def releaseTime() {
    return new Date().format("yyyy-MM-dd-HH-mm-ss", TimeZone.getTimeZone("UTC"))
}

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    signingConfigs {
        xiaomi {
            keyAlias 'xiaomi'
            keyPassword 'xiaomi123'
            storeFile file('xiaomi.keystore')
            storePassword 'xiaomi123'
        }
        baidu {
            keyAlias 'baidu'
            keyPassword 'baidu123'
            storeFile file('baidu.keystore')
            storePassword 'baidu123'
        }
    }
    defaultConfig {
        applicationId "net.ljt.gradledemo"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            // 不显示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            minifyEnabled true
            shrinkResources true //移除无用资源
            debuggable false
            zipAlignEnabled true //zipalign优化
            signingConfig signingConfigs.hxtx
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            // 自定义输出配置
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        def fileName = "${variant.flavorName}_${variant.versionName}_${releaseTime()}.apk"
                        output.outputFile = new File(outputFile.parent, fileName)
                    }
                }
                //过滤掉unaligned的包
                variant.assemble.doLast {
                    variant.outputs.each { output ->
                        File unaligned = output.packageApplication.outputFile;
                        File aligned = output.outputFile
                        if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {
                            unaligned.delete()
                        }
                    }
                }
            }
        }
    }
    productFlavors {
        xiaomi {
            applicationId "net.ljt.gradle.xiaomi"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 3
            versionName "1.2"
            signingConfig signingConfigs.xiaomi
            manifestPlaceholders = [AMAP_APIKEY         : "564561543612315AERG5S4561B",
                                    UMENG_APPKEY        : "54asg1s5bvga6g6AfbaG5",
                                    UMENG_MESSAGE_SECRET: "4af5g4aw5fgae565fge44a56ear",
                                    PACKAGE_NAME        : "com.xxxx.xxxx"]
        }
        baidu {
            applicationId "net.ljt.gradle.baidu"
            minSdkVersion 15
            targetSdkVersion 24
            versionCode 2
            versionName "1.1"
            signingConfig signingConfigs.baidu
        }
        huawei {}
        yingyongbao {}
        _360{}

        gradle{}
        gradledemo{}
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.0'
    testCompile 'junit:junit:4.12'
}
上一篇下一篇

猜你喜欢

热点阅读