Gradle常用命令收录

gradlew代表 gradle wrapper,意思是gradle的一层包装。

使用Android Studio新建一个工程之后,其目录结构是这样的:

├── app #Android App目录
│   ├── app.iml
│   ├── build #构建输出目录
│   ├── build.gradle #构建脚本
│   ├── libs #so相关库
│   ├── proguard-rules.pro #proguard混淆配置
│   └── src #源代码,资源等
├── build
│   └── intermediates
├── build.gradle #工程构建文件
├── gradle
│   └── wrapper
├── gradle.properties #gradle的配置
├── gradlew #gradle wrapper linux shell脚本
├── gradlew.bat
├── LibSqlite.iml
├── local.properties #配置Androod SDK位置文件
└── settings.gradle #工程配置

常用

下面介绍一些常用命令:

./gradlew -v 查看gradle版本号
./gradlew clean 清除项目/app目录下的build文件夹
./gradlew build 检查依赖并编译打包

试运行build。如果你想知道某个task执行时那些task会被一起执行,但是你又不想真正的执行这些task,可以使用-m来试运行。

gradle -m build

build 某个指定 module

$ ./gradlew -p app clean build

明确指定不执行某个 task

$ ./gradlew build -x test -x lint

打包

./gradlew assembleDebug 编译并打Debug包
./gradlew assembleRelease 编译并打Release的包
./gradlew installRelease Release模式打包并安装
./gradlew uninstallRelease 卸载Release模式包

依赖关系

显示tasks任务的依赖关系

gradle tasks --all

查看指定阶段的依赖关系

使用gradle dependencies 可以查看项目中包的依赖关系。不过是列出了所有阶段的依赖,如果项目中依赖复杂的话看起来有点头痛。那么可以使用–configuration来查看指定阶段的依赖情况。

gradle -q dependencies

项目依赖清单

运行命令 gradle dependencies project:dependencies ,多个项目以空格分隔,显示项目的依赖列表,树状显示。

gradle -q dependencies test1:dependencies test2:dependencies

查看testComiple的依赖关系

gradle -q dependencies --configuration testCompile

查看指定dependency的依赖情况。 假如我想查看项目中有没有引入junit,那些阶段引入了junit,那么可以使用dependecyInsight来查看。

gradle dependencyInsight --dependency junit --configuration testCompile

注意dependencyInsight默认只会查看compile阶段的依赖,如果要查看其他阶段可以使用–configuration来指定。

执行 gradle -q webapp:dependencyInsight --dependency groovy --configuration compile 输出

> gradle -q webapp:dependencyInsight --dependency groovy --configuration compile
    org.codehaus.groovy:groovy-all:2.3.6
    \--- project :api
         \--- compile

项目属性清单

运行命令 gradle properties,输出api所有项目属性列表

gradle -q api:properties

加速编译

(1)有一个减少时间的方法:我们需要尽早的让gradle去配置,幸运的是,这只是另外的一种添加命令标志:

./gradlew :android:assembleDebug --dry-run --profile --configure-on-demand

配置这样一个命令对gradle是一个孵化的功能,所以它不是默认启用的。或许将来的一天可以默认开启,但是现在我们可以全局使用它,通过在你的home目录下加一行.gradle/gradle.properties,
这个命令也满足在linux和OSX系统下:

echo 'org.gradle.configureondemand=true' >> ~/.gradle/gradle.properties

(2)使用gradle daemon
gradle daemon的作用就是限制所有的开销。因此可以使用它

./gradlew :android:assembleDebug --dry-run --no-daemon
# vs. 
./gradlew :android:assembleDebug --dry-run --daemon

使用gradle daemon要比不适用快的不是一点点,用gradle daemon确实很棒,所以你应该把它设置成全局的。

echo 'org.gradle.daemon=true' >> ~/.gradle/gradle.properties

build.gradle

gradle允许你使用transitive属性来排除所有的传递依赖

dependencies {
	cargo('org.codehaus.cargo:cargo-ant:1.3.1') {
	transitive = false
	}
	// 选择性的声明一些需要的库
}

库重复冲突

这个时候,在 module 的 build.gradle 的 dependency 添加依赖时,加入 exclude 规则:

compile ('com.bugtags.library:bugtags-lib:latest.integration') {
        exclude group: 'com.android.support', module: 'support-v4'
}

在Gradle 进行dex的可能会遇到内存不够用的情况,错误信息大概是java.lang.OutOfMemoryError: GC overhead limit exceeded。这个时候只需要配置dexOptions的javaMaxHeapSize大小即可,我这里配置4g:

dexOptions {
    javaMaxHeapSize "4g"
}

下载不到特定的版本
Maven 和 Gradle 都会有一个缓存库,默认安装的情况下,是在用户根目录下的 .m2 或者 .gradle 文件夹中。
可以尝试删除里面的文件。例如将 Gradle 的 cache 文件删除:

rm -rf ~/.gradle/caches/

动态设置

resValue

使用 gradle 在编译时动态设置 Android resValue

修改 res value 的方式,比如修改 strings.xml 文件中的 AppName 的值

在你的 gradle 文件 buildTypes 或者 productFlavors 下面,如 release 体内写上类似:

resValue "string", "AppName", "app1"

意为把名为 AppName 的 string value 值改为 app1

BuildConfig

使用 gradle 在编译时动态设置 Android BuildConfig

在你的 gradle 文件 buildTypes 或者 productFlavors 下面,如 release 体内写上类似:

buildConfigField "String", "ENDPOINT", "\"http://example.com\""

gradle sync 一下后,BuildConfig.ENDPOINT 就会被赋值为 http://example.com 就可以供 Java 代码调用了。

manifestPlaceholders

使用 manifestPlaceholders 时动态设置 Android Manifest

manifestPlaceholders 可以替换 AndroidManifest.xml 文件中的标签,可以自定义标签用来替换需要的文本。

如果同一个 activity 在不同 flavor 的 AndroidManifest.xml 中要设置不同的 launchmode,是不能直接在 androidmanifest 文件里面写不同的 launchmode 的,因此我们需要在 gradle 编译的时候动态的给 launchmode 设置值,这就需要使用到 manifestPlaceholders。

基本用法:

(1)在build.gradle文件里面定义 manifestPlaceholders[“key1”:“value1”, “key2”:“value2”, “key3”:“value3” …]

(2)然后在 AndroidManifest.xml 里面引用 android:launchMode="${key1}"

举例目标:A应用普通版本没有桌面图标,需要从设置应用里面跳转;debug 版本有一个测试的 launch 界面并有桌面图标;海外版有桌面图标并有正式的 launch 界面。

在 build.gradle 文件中定义:

//默认的配置
defaultConfig {
    minSdkVersion 19
    applicationId 'com.gradle.example'
    targetSdkVersion 23
    versionCode Integer.parseInt(project.VERSION_CODE)
    versionName project.VERSION_NAME
    manifestPlaceholders = [
            LAUNCH_MODE     : "singleTask",
            LAUNCH_PAGE_NAME: "com.gradle.example.test.TestActivity",
            LAUCH_PAGE_CATEGORY: "android.intent.category.LAUNCHER"
    ]
}

在 gradle.properties 文件中定义 versioncode 和 viersioname,然后通过 Integer.parseInt(project.VERSION_CODE)、project.VERSION_NAME 引用。

默认配置中,使用 manifestPlaceholders 定义了 activity 的启动模式,launch 页面的activity 和 activity 的 category(决定是否有桌面图标)。

我们再定义两个 flavor 维度:

productFlavors {
    //海外版
    international {
        manifestPlaceholders = [
                LAUNCH_MODE        : "singleTop",
                LAUNCH_PAGE_NAME   : "com.gradle.example.MainActivity",
                LAUCH_PAGE_CATEGORY: "android.intent.category.DEFAULT"
        ]
    }
    //国内普通版
    internal {
        manifestPlaceholders = [
                LAUNCH_MODE     : "singleTask",
                LAUNCH_PAGE_NAME: "com.gradle.example.test.TestActivity",
                LAUCH_PAGE_CATEGORY: "android.intent.category.LAUNCHER"
        ]
    }
}

海外 release 版有桌面图标,所以 debug 版本就不需要桌面图标了,TestActivity 页面的 category 为 DEFAULT 类型,MainActivity 页面的category 为 LAUNCHER 类型。点击桌面打开的首页面是 MainActivity,launchMode 值则是 singleTop,这样进入首页打开二级页面后,回到桌面再次点击桌面图标启动应用还是到刚才的二级页面。

国内 release 普通版没有桌面图标,但为了平时开发的方便在 debug 版本设置了个桌面图标,TestActivity 页面的 category 为 LAUNCHER 类型。为了从设置应用里面跳转到A应用时,上滑任务栏看到的A应用图标不是设置应用的图标,即A应用的首页和设置应用不在同一个 stack,所以 launchMode 设置成 singleTask。

main 文件夹里面 AndroidManifest.xml 的定义:

<activity
            android:name=".MainActivity"
	    android:launchMode="${LAUNCH_MODE}"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
</activity>

debug 文件夹里面 AndroidManifest.xml 的定义:

<activity 
	android:name="${LAUNCH_PAGE_NAME}"
	android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="${LAUCH_PAGE_CATEGORY}" />
            </intent-filter>
</activity>

international 文件夹里面的 AndroidManifest.xml 的定义:

<activity
            android:name="${LAUNCH_PAGE_NAME}"
	    android:launchMode="${LAUNCH_MODE}"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="${LAUCH_PAGE_CATEGORY}" />
            </intent-filter>
</activity>

至此,我们可以用同一套代码,编出不同需求的apk(有无桌面图标和 设置相同 activity 的 不同 launchMode)。

参考

文章目录
  1. 1. 常用
  2. 2. 打包
  3. 3. 依赖关系
  4. 4. 加速编译
  5. 5. build.gradle
  6. 6. 动态设置
    1. 6.1. resValue
    2. 6.2. BuildConfig
    3. 6.3. manifestPlaceholders
  7. 7. 参考
|