这篇文章本来是第二天就更的,结果发现,更进一步研究build.gradle,结果发现,好多东西自己都迷迷糊糊的,就怕自己写出来误导别人;加上突然袭来的上线、bug,忙成一团。
这篇文章继续吃build.gradle(:app)吧。这篇文章主要基于google官方的文章Android Developers官方文档
plugin
这一块不是不想讲,而是,这一块对开发需求不大,而且对我而言是超纲的。
android
applicationId
applicationId是apk对外发布的识别码。一般只有在plugin为application的情况下才会有,library下的build.gradle下的plugin为library,且没有applicationId。
做一个测试,新建一个项目,同时新建一个common的module。如图所示,
此时两个moduel的plugin都是
com.android.application
且,app下的id为com.example.helloworld,common下的id为com.example.common,此时会发现,工具栏绿色小机器人的图标旁的名称从app变为common,切换不同的name(app和common),分别点击run,创建了两个不同的app图标,一个是helloworld,另一个是common。
然后将build.gradle(:common)下的plugins有com.android.application改为com.android.library,此时applicationId失效,绿色机器人头像带红叉,能run的只剩下一个app。
同样,同一个app,如果修改了applicationId,那么这个项目(马甲包相关)虽然还是原来的app,但是对手机、应用市场而言,这个将会是一个全新的app。不过现在各大应用市场对马甲包的审核是非常严格的。
另外,接入一些服务(类似推送服务,地图服务)时,需要根据applicationId申请新的appKey或者appId,重新对接入的服务进行配置。
小贴士:引入依赖库的时候,也可以根据文件下右下角的图标判断这个依赖库是否正确引入,如果连图标都没有,去setting,gradle添加一下包含的依赖库吧。
buildTypes和Variants
翻译过来便是构建类型,这个感觉可以和变体一起分析。 默认情况下,buildTypes有两个分支,release和debug(这个甚至在gradle中不会示例出来)。
在buildTypes的release分支下加上一段代码
jnidebug {
minifyEnabled true
jniDebuggable true
}
重新编译后点击AS左下角的Build Variants,然后在弹出的窗口下的Active Build Variant下的build,会发现,原来的两个选项‘debug’、‘release’多了一个‘jnidebug’,
默认的情况下,:app对于的variant是debug,程序在AS中运行的版本也是debug。同理,如果将:app的debug改为release,那么AS点击run按钮,运行的便是release版本。此时app目录下的build/outputs/apk文件夹下有三个文件目录:debug、release、jnidebug(前提是有切换到这个变体并Make Project)。
还有一个小技巧。
假如在buildTypes下的release和debug下添加代码
如此情况下,在as中运行时,调用BuildConfig.URL时,访问的地址是
https://cn.bing.com/
而打包release时访问BuildConfig.URL的地址便是
https://www.baidu.com
省去了在代码中设置链接的麻烦,同时也避免了打包忘记更换链接的问题。
然后就是variants变体,这个一般是基于不同渠道打对于渠道的包。不过这里还是推荐使用360加固,签名+多渠道+加固,一步到位。
minifyEnabled
是否混淆,配合proguardFiles一起食用。
proguardFiles 混淆文件
我遇到一种情况,本地运行代码没有问题,但打包apk文件依赖的库就无法运行,客服那边的反馈是需要添加混淆。这里推荐一篇文章Android 混淆
other
还有其他的一些诸如zipAlignEnabled对齐、debuggable是否可调式(不建议在release中开启,release默认关闭)、ndk.abiFilters等就不一样举例了。
还有,打包apk时,生产的包名app—release.apk不够优雅,而且,每次还得根据版本号修改apk,太麻烦了。
打住!记住这段代码
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "app_name_${variant.versionName}_${variant.name}.apk"
}
}
当然,这只是最初的用法。variant也经常用于渠道分发,这个又是另一个坑了(其中涉及到360加固,又可有牵扯出好多内容,当然,主要还是我不懂)。
dependencies
依赖冲突
开发的过程中依赖库多了,就有可能出现依赖冲突--A依赖C,B同时也依赖C。
最常见的解决方法就是---我不依赖了。
开个玩笑
implementation "com.explame.demo" {
exclude group 'xxxx'
}
在com.explame.demo这个依赖库中去除xxxx库,使xxxx库独属于com.explame.demo。
也可以用compileOnly规避依赖冲突,不过目前官方不推荐使用compile,推荐使用implementation和api。这两者的区别在于是否可继承。
A依赖X库,B依赖A。如果使用implementation,那么B不会依赖X;如果使用api,B也能使用X库。
结语
gradle的浅层就到这里了,基本的开发到这里就够用了(就我个人而言,到这里已经够我4年的开发经验了),当然,我是躺平类型的程序员,不思进取,不求上进,四年了也才到这里...