Gradle编译加速

Gradle是Android项目新的编译系统,是基于JVM的进化版的编译工具;它从构建工具(如Ant 和Maven)汲取了经验教训。随着Android项目变得越来越复杂,模块化的开发实践变得越来越流行,编译性能至关重要。在每次编译时节省几秒能大大提高效率。
gradle assemble 生成所有渠道的Debug和Release包
gradle assembleDebug 生成所有渠道的Debug包
gradle assembleRelease 生成所有渠道的Release包
gradle assemblexxx 生成某个渠道的Debug和Release包

你可能已经意识到,即使最简单的Gradle 可以说相当慢,这里有一些提示,以提高gradle 任务的执行性能:

  • Gradle守护进程
    你可以减少Gradle的启动时间,如果你告诉Gradle使用守护进程来编译:

org.gradle.daemon=true

  • 并行执行工程
    如果你正在建立一个非常复杂的项目,并且有很多依赖的子模块,这会带来很大的不同:
    多module依赖复杂慎用

org.gradle.parallel=true

  • 按需配置项目
    执行任务之前Gradle会配置每个项目,不管实际上该项目是否需要特定的编译。“按需配置”模式更改此行为,只配置所需的项目。像并行模式,按需配置会有很大影响对于多模块依赖的构建。

  • 全局的gradle.properties
    在我们的主目录中的属性文件中定义的属性优先于项目目录,因为你想在构建服务器上避免使用守护,在内存耗用比启动时间更重要的地方。
    /Users/用户/.gradle/gradle.properties

# The Gradle daemon aims to improve the startup and execution time of Gradle.
# When set to true the Gradle daemon is to run the build.
org.gradle.daemon=true

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true

# Enables new incubating mode that makes Gradle selective when configuring projects.
# Only relevant projects are configured which results in faster builds for large multi-projects.
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:configuration_on_demand
org.gradle.configureondemand=true
  • Modules 消耗很高
    如果该模块不经常修改,重要的是要考虑到这一点:从头开始编译需要时间,甚至检查以前的单个模块构建是否是最新的。依赖.jar/.aar效率更高。

优化 lint 任务执行时间

gradle build -x lint

更进一步

gradle build -x lint -x lintVitalRelease

屏蔽不需要的Task
提示 :如果你想从增量构建永久地跳过lint检查,在build.gradle添加:

//屏蔽系统Task
tasks.whenTaskAdded { task ->
    if (task.name.equals("lint") //跳过lint检查
    || task.name.equals("clean") //如果instant run不生效,把clean这行去掉
    || task.name.equals("Aidl") //如果项目中有用到aidl,不可以舍弃这个任务
    || task.name.equals("mockableAndroidJar") //用不到测试的时候,可以先关闭
    || task.name.equals("UnitTest")
    || task.name.equals("AndroidTest")
    || task.name.equals("Ndk")  //用不到NDK和JNI时候,可以先关闭
    || task.name.equals("Jni") 
    ) {
        task.enabled = false
    }
}
//屏蔽指定Task
gradle.taskGraph.whenReady {
	tasks.each { task ->
		if(task.name.contains("XXX") {
			task.enabled = false
		}
	}
}

原文:
https://android.jlelse.eu/speeding-up-gradle-builds-619c442113cb#.fwotrutph

官方关于Gradle的实用建议:

  • 通过productFlavors设置build variant,针对不同的product保留对应的配置信息,加速构建,类似多渠道打包。
  • 避免编译不必要的资源,如只使用英文string资源和xxhdpi的屏幕密度资源。
  • 多渠道打包,本质是使用productFlavors ,结合占位符与AndroidManifest.xml的使用,可以为不同渠道设置不同包名。
productFlavors {
	dev {
		applicationIdSuffix ".debug" //不同包名设置,便于线上和开发包安装在同一手机
		resConfigs "en", "xxhdpi"
	}
	googlepay {}
	xiaomi {}
	tencent {
		manifestPlaceholders = [UMENG_CHANNEL: "Tencent"] //结合占位符
	}
}
  • 用静态的版本依赖,避免使用+号。
  • 建议使用library模块,模块化代码抽离。

Gradle通用技巧

  • Log开关控制。定义动态编译生成对象,通过buildConfigField控制,然后在代码中通过BuildConfig.enableLog来获取。
buildTypes {
	debug {
		buildConfigField("boolean", "enableLog", "true")
	}
	release{
		buildConfigField("boolean", "enableLog", "false")
	}
}
  • 版本号、依赖统一管理。新建独立的gradle(config.gradle),然后apply from进当前的gradle,通过设置projext.ext,再通过rootProject.ext进行引用。
ext {

    abortOnLintError = false
    checkLintRelease = false

    android = [compileSdkVersion        : 24,
               buildToolsVersion        : "25.0.2",
               applicationId            : "com.skyseraph.xknife",
               applicationIdUserLogin   : "com.skyseraph.xknife.mod.userlogin",
               applicationIdLaunch      : "com.skyseraph.xknife.mod.launch",
               applicationIdUpgrade     : "com.skyseraph.xknife.mod.upgrade",
               minSdkVersion            : 15,
               targetSdkVersion         : 24,
               versionCode              : 1,
               versionName              : "0.0.1",
               testInstrumentationRunner: "android.support.test.runner.AndroidJUnitRunner"
    ]

    def supportVersion = "24.2.1"
    def daggerVersion = "2.5"


    def retrofitVersion = "2.1.0"
    def okhttpVersion = "3.5.0"
    def rxandroidVersion = "1.2.1"
    def okioVersion = "1.9.0"
    def gsonVersion = "2.8.0"
    def glideVersion = "3.6.1"
    def butterKnifeVersion = "8.1.0"
    def leakcanary = "1.5.1"
    def aspectVersion = "1.8.9"

    dependencies = ["appcompat-v7"               : "com.android.support:appcompat-v7:${supportVersion}",
                    "design"                     : "com.android.support:design:${supportVersion}",
                    "appcompat-v4"               : "com.android.support:support-v4:${supportVersion}",
                    "recyclerview-v7"            : "com.android.support:recyclerview-v7:${supportVersion}",
                    "cardview-v7"                : "com.android.support:cardview-v7:${supportVersion}",
                    "junit"                      : "junit:junit:4.12",

                    // inject library
                    "butterknife"                : "com.jakewharton:butterknife:${butterKnifeVersion}",

                    // graphics library
                    "glide"                      : "com.github.bumptech.glide:glide:${glideVersion}",
                    "gson"                       : "com.google.code.gson:gson:${gsonVersion}",

                    // retrofit + okhttp
                    "retrofit:retrofit"          : "com.squareup.retrofit2:retrofit:${retrofitVersion}",
                    "retrofit:adapter-rxjava"    : "com.squareup.retrofit2:adapter-rxjava:${retrofitVersion}",
                    "retrofit:converter-gson"    : "com.squareup.retrofit2:converter-gson:${retrofitVersion}",
                    "retrofit;converter-scalars" : "com.squareup.retrofit2:converter-scalars:${retrofitVersion}",
                    "okhttp3:okhttp"             : "com.squareup.okhttp3:okhttp:${okhttpVersion}",
                    "okhttp3:logging-interceptor": "com.squareup.okhttp3:logging-interceptor:${okhttpVersion}",
                    "okio"                       : "com.squareup.okio:okio:${okioVersion}",
                    "rxandroid"                  : "io.reactivex:rxandroid:${rxandroidVersion}",

                    // aspectjrt
                    "aspectjrt"                  : "org.aspectj:aspectjrt:${aspectVersion}",

                    // leakcanary
                    "leakcanary_debug"           : "com.squareup.leakcanary:leakcanary-android:${leakcanary}",
                    "leakcanary_release"         : "com.squareup.leakcanary:leakcanary-android-no-op:${leakcanary}",
                    "leakcanary_test"            : "com.squareup.leakcanary:leakcanary-android-no-op:${leakcanary}",
    ]
}

//使用
applicationId rootProject.ext.android["applicationId"]
  • apk输出名字定制化
applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def fileName = "XKnife-${variant.buildType.name}-${variant.versionName}-${variant.productFlavors[0].name}.apk".toLowerCase()
            def outFile = output.outputFile
            if (outFile != null && outFile.name.endsWith('.apk')) {
                outputFileName = fileName  //  output.outputFile 改为 outputFileName
            }
        }
    }
  • 构建不同的名称,版本号和AppID。
	buildTypes {
        // minifyEnabled 混淆处理
        // shrinkResources 去除无用资源
        // signingConfig 签名
        // proguardFiles 混淆配置
        // applicationIdSuffix 增加APP ID的后缀
        // debuggable 是否保留调试信息

        debug {
            minifyEnabled false
            debuggable true
            applicationIdSuffix ".debug" //构建不同AppId
            versionNameSuffix "-debug"
            resValue "string", "app_name", " XXX(debug)"
            signingConfig signingConfigs.debug

            manifestPlaceholders = [UMENG_APPKEY_VALUE: "xxxxxxxx"] // 替换AndroidManifest中的占位符
            buildConfigField "String", "UMENG_APPKEY", "\"xxxxxxx\""
            buildConfigField "String", "HOST", "\"http://100.100.100.100:8888\""
            buildConfigField "String", "API_URL", '"http://api.douban.com/v2/"'
        }

        release {
        	resValue "string", "app_name", " XXX"
        	
            manifestPlaceholders = [app_label: "@string/app_name"]
            debuggable false
            minifyEnabled true
            shrinkResources true
            signingConfig signingConfigs.release
//            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro',
                    project(":module:xkm_launch").file("proguard-rules.pro")

            manifestPlaceholders = [UMENG_APPKEY_VALUE: "xxxxxx"]
            buildConfigField "String", "UMENG_APPKEY", "\"xxxxxx\""
            buildConfigField "String", "HOST", "\"http://xxx.xxx.com\""
            buildConfigField "String", "API_URL", '"http://api.douban.com/v2/"'
        }

        preview {
            applicationIdSuffix ".preview"
            debuggable true
            minifyEnabled true
            shrinkResources true
            signingConfig signingConfigs.preview
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
  • 修改默认的Build配置文件名
rootProject.buildFileName = xx.gradle
  • Java版本设置
	compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值