Android新手开发指南-build.gradle篇(二)

223 阅读4分钟

这篇文章本来是第二天就更的,结果发现,更进一步研究build.gradle,结果发现,好多东西自己都迷迷糊糊的,就怕自己写出来误导别人;加上突然袭来的上线、bug,忙成一团。

这篇文章继续吃build.gradle(:app)吧。这篇文章主要基于google官方的文章Android Developers官方文档

plugin

这一块不是不想讲,而是,这一块对开发需求不大,而且对我而言是超纲的。

android

applicationId

applicationId是apk对外发布的识别码。一般只有在plugin为application的情况下才会有,library下的build.gradle下的plugin为library,且没有applicationId。

做一个测试,新建一个项目,同时新建一个common的module。如图所示,

image.png 此时两个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’, image.png

默认的情况下,:app对于的variant是debug,程序在AS中运行的版本也是debug。同理,如果将:app的debug改为release,那么AS点击run按钮,运行的便是release版本。此时app目录下的build/outputs/apk文件夹下有三个文件目录:debug、release、jnidebug(前提是有切换到这个变体并Make Project)。

还有一个小技巧。

假如在buildTypes下的release和debug下添加代码

image.png 如此情况下,在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,推荐使用implementationapi。这两者的区别在于是否可继承。

A依赖X库,B依赖A。如果使用implementation,那么B不会依赖X;如果使用api,B也能使用X库。

结语

gradle的浅层就到这里了,基本的开发到这里就够用了(就我个人而言,到这里已经够我4年的开发经验了),当然,我是躺平类型的程序员,不思进取,不求上进,四年了也才到这里...