gradle动态编译

开发中需要根据不同的用户或者场景,采用不同的逻辑/效果,生成不同的包,但是大部分代码是不变的。如果同时维护两个大致相同的项目,工作会既枯燥又毫无用处,还浪费时间。这时候就该用到gradle的动态编译了。

最近有个项目app,要求可以切换角色,切换之后,基本上一半的字段名称都要改变,后台接口返回的内容有可能也会不一样,还没想到怎么做....感觉这种动态编译也不能实现,各位大虾有什么好办法么?

一、配置gradle

build.gradle中可以包括两个节点:buildTypes和productFlavors

  • buildTypes默认有release和debug两个选项。

  • 我们这里在productFlavors增加Seller和buyer。(假设买家和卖家两种场景)

    
        productFlavors{
    
            buyer{
                applicationIdSuffix ".buyer"
            }
            Seller{
                applicationIdSuffix ".Seller"
            }
        }

    buildTypes和productFlavors组合就有下面4个版本了。

SellerDebug
SellerRelease
buyerDebug
buyerRelease

二、新建项目文件,与src下新建Seller, buyer两个文件夹,并分别创建包名,与相同的类(方法名相同,方法体不同)。如下

这时,只能识别一个buyer,另一个识别不了,没关系,这是在gradle中顺序,默认只编译第一个。在打包时可以选择编译哪个。

三、在mian项目中使用这个方法。

四、为了区分两个包,把apk名改一下。

 //修改生成的apk名字
    applicationVariants.all {
        variant ->
            variant.outputs.each {
                output ->
                    def oldFile = output.outputFile
                    if (oldFile.name.contains('.apk')){
                        def newName = variant.applicationId+'-v' + defaultConfig.versionName + '-'+variant.buildType.name+'.apk'
                        output.outputFile = new File(oldFile.parent, newName)
                    }

                    if (output.zipAlign != null) {
                        output.zipAlign.doLast {
                            output.zipAlign.inputFile.delete()
                        }
                    }
            }
    }

五、打包。

如果想动态修改minifest.xml里的应用名和图标,可以在productFlavors中修改,在minifest.xml中使用。

    productFlavors{
        buyer {
            applicationIdSuffix ".buyer"
            manifestPlaceholders = [
                    app_name: "淘宝买家端",
                    app_icon: "@mipmap/icon_launcher_buyer"]
        }

        seller {
            applicationIdSuffix ".seller"
            manifestPlaceholders = [
                    app_name: "淘宝卖家端",
                    app_icon: "@mipmap/icon_launcher_seller"]
        }
    }
    <application
        android:allowBackup="true"
        android:icon="${app_icon}"
        android:label="${app_name}"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

最后介绍下,动态应用名。有时候需要根据选择的productFlavor和buildType来生成不同的应用名,防止调试、测试时搞混。


def appType;
def appName;
android {
    signingConfigs {
        config {
            keyAlias KEY_ALIAS
            keyPassword KEY_PASSWORD
            storeFile file('../app/tong_key.jks')
            storePassword KEYSTORE_PASSWORD
        }
    }
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.lemon.studykit"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            appType="正式"
            debuggable false
            buildConfigField("String", "generalHost", "\"http://192.168.1.224:8089/\"")

            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }
        debug {
            appType="开发"
            buildConfigField("String", "generalHost", "\"http://192.168.1.224:10001/\"")
            signingConfig signingConfigs.config
        }
        inerTest {
            appType="内测"
            buildConfigField("String", "generalHost", "\"http://192.168.1.69:10001/\"")

            debuggable true
            jniDebuggable false
            signingConfig signingConfigs.config
            minifyEnabled false
            zipAlignEnabled true
        }
    }
    productFlavors {
        apple {
            appName="苹果公司"
        }
        lemon {
            appName="柠檬公司"
        }
    }
    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [
                app_name:  "${appName}-${appType}",
                app_icon: "@mipmap/ic_launcher",
                app_icon_round: "@mipmap/ic_launcher_round"
        ]
    }

    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }
    //修改生成的apk名字
    applicationVariants.all {
        variant ->
            variant.outputs.each {
                output ->
                    def oldFile = output.outputFile
                    if (oldFile.name.contains('.apk')){
                        def newName = variant.applicationId+'-v' + defaultConfig.versionName + '-'+variant.buildType.name+'.apk'
                        output.outputFile = new File(oldFile.parent, newName)
                    }

                    if (output.zipAlign != null) {
                        output.zipAlign.doLast {
                            output.zipAlign.inputFile.delete()
                        }
                    }
            }
    }

    //如果你的as是3.0以后的,outputFile就不能直接替换了,改为以下写法

    applicationVariants.all { variant ->
        variant.outputs.all { output ->  // each 改为 all
            def newName = variant.applicationId+'-v' + defaultConfig.versionName + '-'+variant.buildType.name+'.apk'
            def outFile = output.outputFile
            if (outFile != null && outFile.name.endsWith('.apk')) {
                outputFileName = newName 
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值