简述Android中gradle的简单知识
在Android开发中在项目根目录、app或者其他module中我们都能看到build.gradle
这个文件,我们也知道Android项目的编译和运行都是通过gradle来实现,需要引入第三方库时就找到对应项目的build.gradle
中按照集成文档修修改改引入即可,有可能也不会过多的去关注,这里简单介绍下关于在Android开发中gradle的使用。
-
调整gradle的编译参数(gradle.properties文件中配置)
内存配置:org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
- 堆的内存分配用-Xms和-Xmx
- Xms分配堆最小内存,默认为物理内存的1/64;
- Xmx分配最大内存,默认为物理内存的1/4。
- 非堆内存分配用-XX:PermSize和-XX:MaxPermSize
- XX:PermSize分配非堆最小内存,默认为物理内存的1/64;
- XX:MaxPermSize分配最大内存,默认为物理内存的1/4。
守护进程
org.gradle.daemon=true
并行编译
org.gradle.parallel=true
开启缓存
android.enableBuildCache=true
开启孵化模式
org.gradle.configureondemand=true
更多配置信息,移步Gradle官方文档 - 堆的内存分配用-Xms和-Xmx
-
推荐引用固定版本依赖库
dependencies { compile 'com.google.code.gson:gson:2.2.1' //推荐写法 // compile 'com.google.code.gson:gson:2.+' // 不推荐写法 }
虽然带+号的引用可以保证库是最新的,但更新的新库有没有更改库逻辑而带来的bug是未知的。
-
module和jar的依赖方式
implementation project(':commonlibrary') implementation files('libs/alipaysdk.jar')
-
用exclude关键字解决依赖库冲突问题
如我们在Android项目中集成某个第三方库时,可能第三方库也会引入某个本地已经引入的库,所以就会存在引入多版本的依赖库。- 移除整个组织的库
compile ('com.facebook.fresco:animated-webp:0.13.0') { exclude group: 'com.android.support' // 仅仅写组织名称 }
- 精确移除某个指定库
compile('com.android.support:appcompat-v7:23.2.0') { exclude group: 'com.android.support', module: 'support-annotations' // 写全称 exclude group: 'com.android.support', module: 'support-compat' exclude group: 'com.android.support', module: 'support-v4' exclude group: 'com.android.support', module: 'support-vector-drawable' }
如何产看项目中的第三方库的依赖关系?
执行以下命令行:(如何你想查看某个module的依赖关系,此处的app使用你的module名来替换即可
)-
Windows:
gradlew :app:dependencies > dependencis.txt
-
MAC:
./gradlew :app:dependencies > dependencis.txt
- 移除整个组织的库
-
设置java版本
- 如果是在某个module中设置,那么就在对应module的build.gradle文件中配置:
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
- 如果想要做全局配置,那么就在根目录的build.gradle中配置:
allprojects { repositories { jcenter() } tasks.withType(JavaCompile) { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } }
- 如果是在某个module中设置,那么就在对应module的build.gradle文件中配置:
-
在build.gradle中设置productFlavors
android { productFlavors { baidu { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"] } xiaomi { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"] } } }
-
assemble是Gradle中的编译打包命令
- 打包baidu渠道的release版本
gradlew assembleBaiduRelease
- 打包baidu渠道的debug版本
gradlew assembleBaiduDebug
- 生成baidu渠道的Release和Debug版本
gradlew assembleBaidu
- 打包全部渠道Release版本
gradlew assembleRelease
- 打包baidu渠道的release版本
-
为各渠道设置各自的配置信息
android { productFlavors { baidu { applicationId "com.liujc.demo.baidu" manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu", APP_NAME : "app应用01", //app名称 ] buildConfigField "String", "API_APP_ID", "\"10001\"" } xiaomi { applicationId "com.liujc.demo.xiaomi" manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi", APP_NAME : "app应用02", //app名称 ] buildConfigField "String", "API_APP_ID", "\"10002\"" } } }
如何使用?
如上的applicationId
和manifestPlaceholders
中信息在AndroidManifest
中使用如下:android:label="${APP_NAME}" <uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" />
而
buildConfigField
中的参数在代码中使用BuildConfig.API_APP_ID
。 -
Android Studio 为多渠道执行自定义名称打包命令:
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')) { // 计划输出apk名称为App_V1.0.0_baidu.apk def fileName = "App_V${variant.productFlavors.versionName}_${variant.productFlavors.name}.apk" output.outputFile = new File(outputFile.parent, fileName) } } }
下面是多渠道配置:
android { productFlavors { baidu { applicationId "com.liujc.demo.baidu" versionCode 1 versionName "1.0.0" manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu", APP_NAME : "app应用01", //app名称 ] buildConfigField "String", "API_APP_ID", "\"10001\"" } xiaomi { versionCode 2 versionName "1.0.1" applicationId "com.liujc.demo.xiaomi" manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi", APP_NAME : "app应用02", //app名称 ] buildConfigField "String", "API_APP_ID", "\"10002\"" } } }
打包成功后你会发现包名为:
App_V[1.0.0]_[baidu].apk
,这不是我想要的啊,怎么都多了个中括号呢,修改打包代码: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')) { // 计划输出apk名称为App_V1.0.0_baidu.apk def fileName = "App_V${variant.productFlavors[0].versionName}_${variant.productFlavors[0].name}.apk" output.outputFile = new File(outputFile.parent, fileName) } } }
再重新打包,成功后发现包名为:
App_V1.0.0_baidu.apk
OK了。 -
打包时相关属性介绍
name:build type的名字
applicationIdSuffix:应用id后缀
versionNameSuffix:版本名称后缀
debuggable:是否生成一个debug的apk
minifyEnabled:是否混淆
proguardFiles:混淆文件
signingConfig:签名配置
manifestPlaceholders:清单占位符
shrinkResources:是否去除未利用的资源,默认false,表示不去除。
zipAlignEnable:是否使用zipalign工具压缩。
multiDexEnabled:是否拆成多个Dex
multiDexKeepFile:指定文本文件编译进主Dex文件中
multiDexKeepProguard:指定混淆文件编译进主Dex文件中
以下开发中开发中常用的gradle命令
- 生成Android项目的依赖文件并导出
gradlew :app:dependencies > dependencis.txt
- 查看编译日志详细信息
gradlew compileDebugSource --stacktrace -info
- 输出项目debug编译日志
gradlew assembleDebug --info>log2.txt