美文网首页
使用Gradle动态配置资源

使用Gradle动态配置资源

作者: 5e1b18effb55 | 来源:发表于2017-01-12 11:33 被阅读0次
    使用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{}
        }
    

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

    • 在这里你可以指定你的包名,版本号,版本ID,签名文件等内容
    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文件,只需要在里面指定需要替换的部分即可

    • main里面的string.xml文件
    <resources>
        <string name="app_name">GradleDemo</string>
        <string name="hello_world">Hello world!</string>
        <string name="action_settings">Settings</string>
    </resources>
    
    • _360里面的配置string.xml
    <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'
    }
    

    相关文章

      网友评论

          本文标题:使用Gradle动态配置资源

          本文链接:https://www.haomeiwen.com/subject/arddbttx.html