每周一次,深刻学习Android教程,TeachCourse今天带来的一篇关于Android Studio构建文件build.gradle
的相关配置,重点学习几个方面的内容:一、applicationId
和package
属性值的关系,二、怎么配置安全的自定义签名,三、两种构建类型的区别,四、为何要定制产品的偏好配置?,五、怎么才能加快DEX文件的生成速度,六、为何要将一个apk拆分红多个?,七、关于引入依赖包你不知道的秘密。经过这篇文章的学习,你会对build.gradle
文件有一个全新的认识,能够将TeachCourse文章提到的相关说明做为文档参考,方便在另外一个module中引入,代码以下:html
apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion "25.0.2" /** * 1、默认产品偏好配置 */ defaultConfig { ... } /** * 2、自定义签名配置 */ signingConfigs { config { ... } } /** * 3、构建类型,分为release和debug两种 */ buildTypes { release { ... } debug { ... } } /** * 4、自定义产品偏好配置,能够定义多个偏好产品 */ productFlavors { demo { applicationId "cn.teahcourse.demo" versionName "1.0-demo" signingConfig signingConfigs.config } personal{ ... } enterprise{ ... } } /** *5、DEX文件构建属性配置(加快构建速度) */ dexOptions { ... } /** * 6、将一个apk拆分红多个相关配置(拆分依据:屏幕密度、系统架构) */ splits { density { ... } abi { ... } } } /** * 7、引入依赖包的秘密 */ dependencies { ... }
applicationId
和package
属性值的关系Android Studio开发工具建立module的时候,默认在build.gradle
文件生成一个applicationId
,对应的属性值是填写的package name,以下图:java
这时候的applicationId
和package
属性值同样,刚开始接触Android Studio的时候,TeachCourse就据说applicationId
表示真正的包名,而package
再也不被认为是包名,由于应用程序被打包成apk文件的时候,原先在manifest声明的package
被applicationId
代替,也就是说若是你的build.gradle
文件添加了applicationId
属性值,不管二者是否同样,打包的apk文件的package
属性值等于applicationId
,若是不信,TeachCourse先来作过实验,将applicationId
改成cn.teachcourse.demo
,将package
改成cn.teachcourse
,而后将module打包成apk文件,使用反编译工具apktool.exe,以下图:android
最后,打开AndroidManifest.xml
文件,以下图:nginx
结果证实:cn.teachcourse
被cn.teachcourse.demo
代替django
正是由于打包的apk文件的package
的属性值被applicationId
代替,也恰好说明为何应用程序安装到手机后,手机上显示的是applicationId
,而不是显示package
,同时若是想在应用程序中接入第三方的API,填写的包名也必须是applicationId
,常见的例子有:1.接入微信的支付功能,2.接入微信的分享功能,3.集成百度地图的定位功能缓存
那么,AndroidManifest.xml的package
到底有什么用呢?尽管,package
在打包成apk的时候被applicationId
代替,可是在构建的时候package
有两方面的做用:安全
第一个做用:在package
指定的目录下,生成对应的R.java
文件,上面的例子,构建的时候,生成R文件的目录,以下图:ruby
app\build\generated\source\r\demo\debug\cn\teachcourse\R.java
第二个做用:在package
指定的目录下,引用对应的activity
、server
组件,以下图:bash
<!-- 定义Activity --> <activity android:name=".MainActivity"/> <!-- 添加service组件 --> <service android:name=".service.music.MusicService" />
在上面反编译的AndroidManifest.xml文件中,查看对应的组件目录,以下图:服务器
也就是说,manifest指定的组件无论使用相对路径仍是绝对路径,打包成apk文件后,都变成绝对路径,结构是:package.组件
须要特别注意的问题有:
第一个问题:代码中使用getPackageName()
或getPackageManager()
对应的方法,返回的是applicationId
属性值
第二问题:使用WebView
基本存放于res/raw
内的文件时,若是applicationId
不等于package
,提示ClassNotFoundException
异常(多是官方的bug),TeachCourse测试后找到两个解决的办法
res/raw/note.html
文件移动到assets
文件夹下,更换资源文件加载路径mWebView.loadUrl("file:///android_asset/note.html");
applicationId
属性值和package
属性值一致<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.teahcourse.demo"> ... </manifest>
自定义签名指的是使用开发者导出的密钥库对apk文件进行签名,关于怎么生成本身的密钥库,不懂的同窗,能够后面看一下TeachCourse另外一篇文章《Android Studio运行时自带签名配置过程详解》,文章介绍了怎么配置Android Studio的运行时签名,这样作的目的:在接入一些须要自定义签名的API时,方便直接调试。
这里,介绍的是安全的自定义签名,即怎么才让别人看不到咱们在build.gradle
写入的密码(包括别名密码、密钥库密码),关于签名文件的重要性,TeachCourse在这里就不说了。
** 2.1 配置安全的自定义签名(1),步骤:**
storePassword=myStorePassword keyPassword=mykeyPassword keyAlias=myKeyAlias storeFile=myStoreFileLocation
这里须要注意:keystore.properties中storeFile
签名文件是相对module目录的路径,即将密钥库文件保存在module根目录下
build.gradle
文件中,于 android {}
块的前面添加用于加载 keystore.properties 文件的代码。...
def keystorePropertiesFile = rootProject.file("keystore.properties") def keystoreProperties = new Properties() keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) android { ... }
注:您能够选择将 keystore.properties 文件存储在其余位置(例如,存储在模块文件夹中而不是项目的根文件夹中,或者若是您使用连续集成工具,也能够存储在构建服务器上)。在这种状况下,您应当修改上面的代码,以便使用实际 keystore.properties 文件的位置正确初始化 keystorePropertiesFile。
keystoreProperties['属性名称']
引用存储在 keystoreProperties 中的属性。修改模块 build.gradle
文件的 signingConfigs
块,以便使用此语法引用存储在 keystoreProperties 中的签署信息。android {
signingConfigs {
config {
keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } ... }
signingConfigs
块做用于release版本或debug版本** 2.2 配置安全的自定义签名(2),步骤:**
android { signingConfigs { config { keyAlias System.getenv("KEYALIAS") keyPassword System.getenv("KEYPWD") storeFile file('release.jks') storePassword System.getenv("KSTOREPWD") } } ... }
KEYALIAS指的是环境变量的变量名,System.getenv("KEYALIAS")
的读取变量名对应的变量值,如图:
KEYPWD,按照上图的方式添加,以下图:
KSTOREPWD以一样的方式,以下图:
须要特别注意的是:第二种自定义签名的方式,须要先检查Android Studio是否已配置了gradle
工具的环境变量,打开Android Studio的terminal窗口,输入:gradle build
,以下图:
若是,你的terminal窗口提示gradle不是内部命令,操做上述步骤以前,你得添加gradle
工具的环境变量,Android Studio的gradle
工具默认存放路径:
C:\Program Files\Android\Android Studio\gradle\gradle-3.2
配置gradle
的环境变量,以下图:
每个APP至少包含debug
和release
两种构建类型,debug
定义APP的调试版本,debug
模式的几个特色:
debuggable
属性值为true
release
定义APP的发布版本,建立项目module中的build.gradle
文件,代码以下:
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
minifyEnable
定义是否压缩代码,false
表示不压缩;proguardFiles
定义混淆代码的默认混淆规则,proguard-android.txt
表示系统自带的混淆规则,proguard-rules.pro
位于当前module根目录下,用于定义开发者本身的混淆规则。
release
模式须要注意的几个特色:
debuggable
默认为falseminifyEnabled
,默认为falseshrinkResources
,默认为false开发者在发布应用程序时,须要对release
模式下的属性配置进行修改,优化apk文件,删除无用的代码和资源文件,混淆类文件和资源名称,自定义签名密钥库,代码以下:
release { shrinkResources true minifyEnabled true useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.config }
总结:debug
和release
模式,最大的区别默认属性配置不同,两种模式支持的属性配置还包括,以下图:
记不住代码的同窗,能够选中Build Types定义的模式,在可选项中改变对应属性配置,Android Studio运行时签名的实质将debug
模式下的Signing Config
设置为自定义密钥库文件,可是TeachCourse随着不断深刻学习后发现,其实debug
模式下配置Signing Config
是画蛇添足,而只要在release
模式下配置Signing Config
就够了,Android Studio的能够方便为咱们生成两种模式下对应的apk文件,在Android Studio的左下角Build Variant中切换,以下图:
下面介绍了产品偏好配置后,回头再看看它们二者之间的关系。
什么是产品的偏好配置呢?好比说,TeachCourse想要开发一个应用程序,包含我的版本personal和企业版本enterprise,这两个版本之间在功能上有所区别,企业版天然比我的版功能要多一些,很明显就是要就一个Android项目打包成两个产品发布,它们之间的要求以下所示:
personal:版本号为1,最低SDK版本定义为11,最高SDK定义为24,版本名称后缀定义为-personal,applicationId后缀定义为-per,签名文件为自定义密钥库,代码以下:
personal { versionCode 1 minSdkVersion 11 targetSdkVersion 24 versionNameSuffix '-personal' applicationIdSuffix '-per' signingConfig signingConfigs.config }
enterprise:版本号为1000,最低SDK版本定义为11,最高SDK定义为24,版本名称后缀定义为-profession,applicationId后缀定义为-pro,签名文件为自定义密钥库代码以下:
enterprise { versionCode 1000 minSdkVersion 11 targetSdkVersion 24 versionNameSuffix '-profession' applicationIdSuffix 'full' signingConfig signingConfigs.config }
同时,TeachCourse定义第三个产品偏好配置为demo,用于上传GitHub,提供下载,代码以下:
demo { applicationId "cn.teahcourse.demo" versionName "1.0-demo" signingConfig signingConfigs.config }
一个Android项目,配置三个偏好的产品,即便修改了项目代码,也能够快速编译并打包三个apk文件,在Android Studio的左下角Build Variant中切换,以下图:
看上面的图片,你是否是发现了什么,忽然间,三个偏好配置的产品,出现了6个变体,一个产品包含debug
和release
两个版本,构建类型和偏好产品之间的关系是:一个偏好产品,确定包含一个debug版本和一个release版本,能够生成变体的总数为flavors*2
,选中须要调试的版本或选中须要发布的版本,Android Studio自动从新构建Android项目,就能够针对指定的产品进行调试或打包,很是的方便吧!
偏好产品相关配置,以下图:
defaultConfig
也属于其中一种偏好产品,在咱们没有定义本身的偏好产品时,咱们构建和编译的就是默认的defaultConfig
这个产品,也就只包含debug
和release
两个变体。
你有没有遇到Android Studio在每次构建的时候,都感受花好长时间,TeachCourse就不止一次和同事抱怨说,Android Studio的编译速度还不如Eclipse快,蜗牛的速度真受不了呀?那该怎么办呢?
Android Studio提供dexOption
区块以便于咱们配置DEX构建属性,加快DEX文件的生成速度,代码以下:
dexOptions { preDexLibraries true maxProcessCount 8 javaMaxHeapSize "2048m" }
preDexLibraries
声明是否预先编译依赖库,从而加快构建速度,实质是经过延时清除已生成的依赖库的构建文件,从而提升构建速度,根据使用状况合理配置。maxProcessCount
设置进程运行过程当中可使用的最大线程数。默认值为4。javaMaxHeapSize
设置DEX编译器的最大堆大小,堆或者栈都是用于存放暂时不用的垃圾,当内存不足时,垃圾回收机制会清除过期的缓存,堆大小决定垃圾清除的频率,影响着构建的速度根据TeachCourse以往的经验,一个apk文件能够支持不一样屏幕密度和不一样ABIs的手机设备,是由于咱们进行了屏幕适配,作法:将市场主流的屏幕密度和ABIs集成到一个apk,形成的影响,若是你的应用程序自己就比较大,集成了不一样屏幕密度和支持不一样ABIs的代码,打包出来的apk文件变得更大,考虑到流量成本和用户体验,减小apk文件的大小其中一种方式将一个apk文件拆分红多个。
Gradle可以单独指定只包含一种屏幕密度或一种ABI代码和资源文件的apk,在build.gradle
文件中使用到splits
区块,splits
区块内同时提供了按屏幕密度拆分的density
区块和按abi拆分的abi
区块,在一个build.gradle
文件中能够同时指定二者或二者中的其中一者,下面分别介绍:
** 6.1 按屏幕密度拆分**
android {
...
splits {
density {
enable true exclude "xxxhdpi" reset() include "ldpi", "xxhdpi" compatibleScreens 'small', 'normal', 'large', 'xlarge' } } }
上面是一个按屏幕密度拆分的一个例子,各个标签的含义是:
enable
,是否基于定义的屏幕密度拆分红多个apk文件,默认为falseexclude
,指定忽略拆分的屏幕密度列表,想要拆分红更多类型的apk文件,该关键字包含的屏幕密度列表应就可能少reset()
,重置默认拆分的屏幕密度依据,而后使用include
标签订义拆分的屏幕密度依据include
,结合reset
一块儿使用,定义拆分的屏幕密度依据compatibleScreens
,指定兼容的屏幕尺寸列表,区别于屏幕密度,该标签将会在清单文件manifest
中经过<compatible-screens>
注入到每个apk文件中,即apk文件只能安装到<compatible-screens>
指定尺寸的手机上按照上面在build.gradle
配置完成后,点击Build APK
后,将在apk文件夹内生成多个apk文件,以下图:
为了验证是否在清单文件中注入指定屏幕尺寸,反编译其中一个apk文件,以下图:
** 6.2 按abi拆分**
android {
...
splits {
abi {
enable true reset() include "x86", "armeabi-v7a", "mips" universalApk false } } }
上面是一个按abi拆分的一个例子,除了universal
标签不同外,其余标签是同样的,使用方法同样,include
标签订义拆分的abi依据,关于abi介绍,参考下面链接:
一样,点击Build APK
后,将在apk文件夹内生成多个apk文件,以下图:
仔细观察生成的apk文件,会发现下面两个规律:
不知道你会不会有和TeachCourse同样的想法,dependencies
区块引入的jar包的名称长,基本没法记住,每一节又表示什么含义?Android Studio引入依赖项有几种方式?让我先看下面的这个例子:
dependencies {
compile project(":mylibrary") compile files('libs/zxing.jar') compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:appcompat-v7:25.1.0' compile group: 'com.android.support', name: 'appcompat-v7', version: '25.1.0' }
能够看到Android Studio引入依赖项的方式分为上述四种,按顺序依次称为:一、模块依赖项,二、本地二进制依赖项,三、本地二进制依赖项,四、远程二进制依赖项,五、远程二进制依赖项
compile project(':mylibrary')
行声明了一个名为mylibrary
的本地 Android 库模块做为依赖项,并要求构建系统在构建应用时编译并包含该本地模块。compile files('libs/zxing.jar')
和compile fileTree(dir: 'libs', include: ['*.jar'])
都称为本地依赖项,告诉构建系统在编译类路径和最终的应用软件包中包含 app/libs/ 目录内的指定或所有 JAR 文件。若是您有模块须要本地二进制依赖项,请将这些依赖项的 JAR 文件复制到项目内部的 中。compile 'com.android.support:appcompat-v7:25.1.0'
和compile group: 'com.android.support', name: 'appcompat-v7', version: '25.1.0'
都称为远程二进制依赖项,经过指定其 JCenter 坐标,针对 Android 支持库的 25.1.0 版本声明了一个依赖项。默认状况下,Android Studio 会将项目配置为使用顶级构建文件中的 JCenter 存储区。当您将项目与构建配置文件同步时,Gradle 会自动从 JCenter 中抽取依赖项。或者,您也能够经过使用 SDK 管理器下载和安装特定的依赖项。第五种能够清楚看出每一节表示的含义,在Android Studio引入远程二进制依赖项,一般的作法是在Library Dependency窗口中搜索,搜索到最新版本的依赖项,以下图:
彷佛没法搜索到低版本的依赖项,若是想要引入低版本的,那该怎么办呢?若是先前不了解远程二进制依赖项的含义,可能想不到修改version
的办法,如今就变得很简单了。
本篇文章在阅读Android Studio用户指南多篇相关文档后完成的,想要更详细深刻学习gradle
指令的同窗,能够继续研读Gradle官网文档,部份内容在TeachCourse开发的项目没有对应的需求,暂时也没有用到,是否使用更多应该根据项目实际状况而定,但能够做为用户开发的例子,先分享和收藏,以备不时之需。
参考资料:
https://developer.android.google.cn/studio/build/application-id.html
https://developer.android.google.cn/studio/build/optimize-your-build.html
https://developer.android.google.cn/studio/build/dependencies.html
https://developer.android.google.cn/studio/build/build-variants.html
版权声明:本文著做权归TeachCourse全部,未经许可禁止转载,谢谢支持!
转载请注明出处:http://teachcourse.cn/2385.html