gradle配置

279 阅读3分钟

1.利用productFlavors分渠道打包

背景:当你需要打包的时候,不同的市场需要打出不同的渠道包;如果一个一个打包太麻烦,就用到了productFlavors分渠道打包,

android {
    compileSdkVersion 28

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        flavorDimensions "fuck"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles 'proguard-rules.pro'
        }
        debug{
            minifyEnabled false
        }
        dev {

        }
    }
    productFlavors {
        xiaomi {
            dimension "fuck"
            applicationId "com.lyhinsuning.multi.channelpackagexiaomi"
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
        }
        _360 {
            dimension "fuck"
            applicationId "com.lyhinsuning.multi.channelpackage_360"
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
        }
        baidu {
            dimension "fuck"
            applicationId "com.lyhinsuning.multi.channelpackagebaidu"
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
        }
        wandoujia {
            dimension "fuck"
            applicationId "com.lyhinsuning.multi.channelpackagewandoujia"
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
        }
    }
}


flavorDimensions "fuck"
flavorDimensions必须要添加上; "fuck"就是productFlavors中每个渠道的dimension的值,
如果dimension的值不同,谁在前面谁优先级就高
比如:
flavorDimensions "fuck","wotou"
那么这时"fuck"优先级较高一些

//在AndroidManifest.xml文件Application标签中添加,这时就可以在java代码中获取相应的渠道包信息了
<meta-data
            android:name="CHANNEL"
            android:value="${UMENG_CHANNEL_VALUE}" />

//在java代码中获取相应的渠道包信息
ApplicationInfo appInfo = null;
try {
    appInfo = getPackageManager().getApplicationInfo(
            getPackageName(), PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
    Log.e("MultiApplication", e.getMessage());
}
if (appInfo != null && appInfo.metaData != null) {
    String envService = appInfo.metaData.getString("CHANNEL");
    Log.e("MultiApplication", envService);
}

2. lintOptions 配置:用于代码检查

android {
    lintOptions {
        // true--关闭lint报告的分析进度
        quiet true
        // true--错误发生后停止gradle构建
        abortOnError false
        // true--只报告error
        ignoreWarnings true
        // true--忽略有错误的文件的全/绝对路径(默认是true)
        //absolutePaths true
        // true--检查所有问题点,包含其他默认关闭项
        checkAllWarnings true
        // true--所有warning当做error
        warningsAsErrors true
        // 关闭指定问题检查
        disable 'TypographyFractions','TypographyQuotes'
        // 打开指定问题检查
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        // 仅检查指定问题
        check 'NewApi', 'InlinedApi'
        // true--error输出文件不包含源码行号
        noLines true
        // true--显示错误的所有发生位置,不截取
        showAll true
        // 回退lint设置(默认规则)
        lintConfig file("default-lint.xml")
        // true--生成txt格式报告(默认false)
        textReport true
        // 重定向输出;可以是文件或'stdout'
        textOutput 'stdout'
        // true--生成XML格式报告
        xmlReport false
        // 指定xml报告文档(默认lint-results.xml)
        xmlOutput file("lint-report.xml")
        // true--生成HTML报告(带问题解释,源码位置,等)
        htmlReport true
        // html报告可选路径(构建器默认是lint-results.html )
        htmlOutput file("lint-report.html")
        //  true--所有正式版构建执行规则生成崩溃的lint检查,如果有崩溃问题将停止构建
        checkReleaseBuilds true
        // 在发布版本编译时检查(即使不包含lint目标),指定问题的规则生成崩溃
        fatal 'NewApi', 'InlineApi'
        // 指定问题的规则生成错误
        error 'Wakelock', 'TextViewEdits'
        // 指定问题的规则生成警告
        warning 'ResourceAsColor'
        // 忽略指定问题的规则(同关闭检查)
        ignore 'TypographyQuotes'
    }
}

3.buildConfigField字段的配置和作用

// 主module的build.gradle中
android{
	defaultConfig {
        applicationId "com.lyh.msdk"
        minSdkVersion 15
        targetSdkVersion 28
        flavorDimensions "default"
        versionCode 1
        versionName "1.0"
        //app id
        buildConfigField "long", "APP_ID", APP_ID
    }
}

同目录下build.properties文件

//然后新建一个build.properties文件,里面添加字段,共build.gradle中使用
APP_ID = 1598282460000L
  • 禁用动态的BuildConfig可以有效减少增量编译的耗时
	如果改一行代码或者资源,执行一次增量build

  gradlew app:assemble -PdevBuild --profile

  耗时也要较长时间,这就很奇怪了,理论上来说,不该一行代码,应该秒编啊,为了搞清楚这个问题,我们加入--info编译选项,找到更多的信息

  gradlew app:assemble -PdevBuild --info | grep -A 3 Executing

  加上--info选项时,如果执行了某个task,会解释其原因,为什么会执行,我们可以根据Executing关键字来找到编译慢的原因

  发现generateXXXBuildConfig 和XXXjavaWithjavac任务被执行,原因是buildConfig的itemValues发生了变化。目光转向build.gradle

  buildConfigField "long", "BUILD_TIMESTAMP", getTimeStamp() + "L"

    我们对BuildConfig中的一项输入做了动态变化,getTimeStamp会获取当前的时间,
    导致每次build时这个值都会发生变化。
    当然在release环境下,这个值确实有用,但是在开发中,就没必要了。
    它会导致重新生成BuildConfig.java, 继而导致 javac, dex, package,sign等一系列的任务重新执行,需要对其优化

  buildConfigField "long", "BUILD_TIMESTAMP",

  project.hasProperty("devBuild")?"000000000":getTimeStamp() + "L"

  这样如果是开发环境,每次这个值都是一样的,就会对编译耗时有很大的改进