SVG(
Scalable Vector Graphics,可缩放的矢量图形)
:就是用于描述二维矢量图形的图形格式。
svg网站:(www.iconfont.cn/collections…
还有在线转化工具。
VectorDrawable
: 从5.0(API等级21)开始,android了支持矢量图,优点:文件比位图要小,可以缩小我们apk体积,并且可以任意放大矢量图形,而不会丢失细节或影响清晰度,在屏幕适配时,只用一套图即可。它是Android
当中的SVG
实现,它并不支持SVG
的全部语法,只是支持部分有必要的部分。
Android 开发 VectorDrawable 矢量图 (二)了解矢量图属性与绘制 - 观心静 - 博客园
Gradle
详解
基本配置:AS
中的Android
项目通常至少包含两个build.gradle
,一个是Project
范围的,另一个是Module
范围的,由于一个Project
可以有多个Module
,所以每个Module
下都会对应一个build.gradle
。
5.1 Project
下的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules. apply from: "config.gradle" buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.1' } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
buildscript
下的repositories
是gradle
脚本自身需要的资源,allprojects
下的repositories
是项目所有模块需要的资源。
5.2 模块的build.gradle
//声明插件,表明这是一个Android程序;如果是库,那么应当是com.android.library apply plugin: 'com.android.application' //Android构建过程需要配置的参数 android { //编译版本 compileSdkVersion rootProject.ext.android.compileSdkVersion //buildTool版本 buildToolsVersion rootProject.ext.android.buildToolsVersion //默认配置,同时应用到debug和release版本上 defaultConfig { applicationId rootProject.ext.android.applicationId minSdkVersion rootProject.ext.android.minSdkVersion targetSdkVersion rootProject.ext.android.targetSdkVersion versionCode rootProject.ext.android.versionCode versionName rootProject.ext.android.versionName testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner } //配置debug和release版本的一些参数,例如混淆,签名配置等 buildTypes { //release版本 release { minifyEnabled false //是否开启混淆 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //混淆文件位置 } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile rootProject.ext.dependencies["support-v7"] androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) testCompile 'junit:junit:4.12' }
下面对Android
构建过程中需要配置的参数做一些解释:
compileSdkVersion
:告诉gradle
用那个Android SDK
的版本编译你的应用,修改它不会改变运行时的行为,因为它不会被包含进入最终的APK
中;因此,推荐使用最新的SDK
编译;如果使用Suppport Library
,那么compileSdkVersion
必须要大于等于它的大版本号。minSdkVersion
:应用最低可运行的要求;它必须要大于等于你所依赖的库的minSdkVersion
;targetSdkVersion
:Android
提供向前兼容的重要依据。(targetSdkVersion is the main way Android provides forward compatibility
)
因为随着Android
系统的升级,某个api
或者模块的行为有可能发生改变,但是为了保证老APK
的行为和以前兼容,只要APK
的targetSdkVersion
不变,那么即使这个APK
安装在新的Android
系统上,那么行为还是保持老的系统上的行为。
系统在调用某个api
或者模块的时候,会先检查调用的APK
的targetSdkVersion
,来决定执行什么行为。
minSdkVersion
和targetSdkVersion
最终会被包含进入最终的APK
文件中,如果你查看生成的AndroidManifest.xml
,那么会发现:
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="7" />
所以,我们一般遵循的规则是:
minSdkVersion (lowest possible) <= targetSdkVersion == compileSdkVersion (latest SDK)
5.3 gradle
相关文件
gradle.properties
配置文件,可以定义一些常量供build.gradle
使用,比如可以配置签名相关信息,例如keystore
位置、密码、keyalias
等。settings.gradle
用来配置多模块的,如果你的项目有两个模块Browser
和ScannerSDK
,那么就需要:
include ':Browser' include ':ScannerSDK' project(':ScannerSDK').projectDir = new File(settingsDir, './ScannerSDK/')
gradle
文件夹
里面有两个文件,gradle-wrapper.jar
和gradle-wrapper.properties
,后者当中指定了gradle
的版本。
distributionUrl=https://services.gradle.org/distributions/gradle-2.8-all.zip
gradlew
和gradlew.bat
分别是Linux
和windows
下的批处理文件,它们的作用是根据gradle-wrapper.properties
文件中的distributionUrl
下载对应的gradle
版本,这样即使环境没有安装gradle
也可以编译。
5.4 gradle
仓库
gradle
有三种仓库:maven/ivy/flat本地
。
maven{ url "..." } ivy{ url "..." } flatDir{ dirs 'xxx' }
有些仓库取了别名:
repositories{ mavenCentral() jcenter() mavenLocal() }
5.5 gradle
任务
通过以下指令,可以看到支持的任务:
./gradlew tasks
Task1.png
Task2.png
六、常见问题
6.1 导入本地Jar
包
导入单个jar
文件:
compile files('libs/xxx.jar')
导入libs
的多个jar
文件:
compile fileTree(dir: 'libs', include: ['*.jar'])
6.2 导入maven
库
compile 'groupId:artifactId:version'
6.3 导入Project
在导入之前,需要在settings.gradle
中把模块包含进来,例如前面的ScannerSDK
模块:
compile project(':ScannerSDK')
6.4 声明第三方maven
库
如果项目中需要的一些库文件不再中央仓库中,而是在某个特定地址里,那么就需要在Project
中的build.gradle
中的allprojects
结点下或者直接配到某个模块中:
allprojects { repositories { maven { url '地址' } } }
6.5 依赖第三方aar
aar: Android库项目的二进制归档文件,包含所有资源,class以及res资源文件全部包含。
jar :只包含了class文件与清单文件 ,不包含资源文件,如图片等所有res中的文件。
compile 'com.aaa.xxx:core:1.0.1@aar'
6.6 将库导出为aar
首先,你的项目必须是一个库项目,之后在build.gradle
中进行配置:
apply plugin : 'com.android.library'
之后,进入到该项目中,执行gradle
命令:
./gradlew assembleRelease
生成的aar
放在/build/output/aar
文件当中
6.7 引用本地aar
首先,将aar
文件拷贝到对应目录下,然后在该模块的build.gradle
中声明flat
仓库:
repositories{ flatDir{ dirs '以build.gradle为根目录的相对路径' } }
之后,在dependencies
结点下依赖该aar
模块:
dependencies{ compile (name:'xxx',ext:'aar') }
七、多版本打包
在此之前,我们先了解几个基本的概念:
buildTypes
:构建类型,Android Studio
的Gradle
组件默认提供了debug
和release
两个默认配置,这里主要用于是否需要混淆,是否调试。productFlavors
:产品渠道,在实际发布中,根据不同渠道,可能需要使用不同的包名,甚至是不同的代码。buildVaiants
:每个buildTypes
和productFlavors
组成一个buildvariant
。
以上我们讨论的buildTypes
和productFlavors
可以通过每个Module
中的build.gradle
的android
标签来配置。
下面,我们先看一下不同的productFlavors
,分别用来支持读取不同的文件和替换不同的字符串。
7.1 引用不同的代码
我们首先在app/src
目录下新建两个目录,分别对应两个Flavor
,再在其中建立相同名字的文件Constant.java
,对里面的某个常量赋予不同的值。
Flavor.png
constantFlavor1
:
package com.example.lizejun.repogradle; public class Constant { public static final String NAME = "flavor1"; }
constantFlavor2
:
package com.example.lizejun.repogradle; public class Constant { public static final String NAME = "flavor2"; }
我们的app
下的build.gradle
中的android
标签下添加如下几行代码,让两个Flavor
分别引用不同的Constant
文件:
sourceSets { constantFlavor1 { java.srcDirs = ['src/constantFlavor1', 'src/constantFlavor1/java', 'src/constantFlavor1/java/'] } constantFlavor2 { java.srcDirs = ['src/constantFlavor2', 'src/constantFlavor2/java', 'src/constantFlavor2/java/'] } } productFlavors { constantFlavor1 {} constantFlavor2 {} }
之后我们进行打包,可以得到以下不同安装包,这两个apk
如果在其中引用的了NAME
,那么它会得到不同的值:
7.2 自定义buildConfig
类
如果我们只需要定义一些简单的值,那么我们可以用buildConfig
类:
productFlavors { constantFlavor1 { buildConfigField "boolean", "BOOLEAN_VALUE", "true" } constantFlavor2 { buildConfigField "boolean", "BOOLEAN_VALUE", "false" } }
7.3 占位符
productFlavors { constantFlavor1 { buildConfigField "boolean", "BOOLEAN_VALUE", "true" manifestPlaceholders = [label:"constantFlavor1"] } constantFlavor2 { buildConfigField "boolean", "BOOLEAN_VALUE", "false" manifestPlaceholders = [label:"constantFlavor2"] } }
之后,我们再在AndroidManifest.xml
中引用它:
android:label="${label}"
7.4 签名配置
首先是在android
标签下,我们使用signingConfigs
来配置不同的签名类型
signingConfigs { eng { keyAlias 'androiddebugkey' keyPassword 'android' storeFile file('debug.keystore') storePassword 'android' } prd { keyAlias 'androiddebugkey' keyPassword 'android' storeFile file('debug.keystore') storePassword 'android' } }
之后,再在buildTypes
的各个分支中引用对应的签名配置:
buildTypes { debug { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.eng } release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.prd } }
7.5 依赖
有时候,我们需要在不同的buildTypes
下,引用不同的依赖,例如内存泄露的检测工具,我们希望在debug
版本时检查内存泄露,并在发生时在桌面上生成图标,但是在release
版本上我们并不希望这么做,这时候我们可以这么写:
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
这样,release
版本就不会在桌面生成内存泄露的图标。