本文是Android面试题整理中的一篇,结合右下角目录食用更佳html
- Gradle是一个自动化构建工具
- 兼容Maven等仓库
- 基于Groovy的特定领域语言来声明名目设置
- Gradle Wrapper是一个脚本文件
- 它会在没有安装Gradle的状况下为咱们下载Gradle,以后咱们就可使用gradlew命令,像使用gradle同样来使用Gradle了
- GradleWraper简化了gradle的安装部署
- settings.gradle:整个Project的配置文件,能够设置包含哪些module
- build.gradle (Project的gradle文件):整个Project的配置文件
- build.gradle(Module):Module的配置文件
- gradle.properties:能够在 gradle.properties 文件中配置一些变量
- gradlew clean: 清除app目录下的build文件夹
- gradlew check: 执行lint检查
- gradlew assemble:打release和debug包
- gradlew build : 执行check和assemble
- gradlew assembleRelease/gradlew assembleDebug:打所有渠道的Release或者debug包
repositories {
jcenter()
}
复制代码
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
复制代码
buildscript{}
复制代码
apply plugin: 'com.android.application'
复制代码
android {
// 编译SDK的版本
compileSdkVersion 22
// build tools的版本
buildToolsVersion "23.0.1"
//aapt配置
aaptOptions {
//不用压缩的文件
noCompress 'pak', 'dat', 'bin', 'notice'
//打包时候要忽略的文件
ignoreAssetsPattern "!.svn:!.git"
//分包
multiDexEnabled true
//--extra-packages是为资源文件设置别名:意思是经过该应用包名+R,com.android.test1.R和com.android.test2.R均可以访问到资源
additionalParameters '--extra-packages', 'com.android.test1','--extra-packages','com.android.test2'
}
//默认配置
defaultConfig {
//应用的包名
applicationId "com.example.heqiang.androiddemo"
minSdkVersion 21
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
//编译配置
compileOptions {
// java版本
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
//源文件目录设置
sourceSets {
main {
//jni lib的位置
jniLibs.srcDirs = jniLibs.srcDirs << 'src/jniLibs'
//定义多个资源文件夹,这种状况下,两个资源文件夹具备相同优先级,即若是一个资源在两个文件夹都声明了,合并会报错。
res.srcDirs = ['src/main/res', 'src/main/res2']
//指定多个源文件目录
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
//签名配置
signingConfigs {
debug {
keyAlias 'androiddebugkey'
keyPassword 'android'
storeFile file('keystore/debug.keystore')
storePassword 'android'
}
}
buildTypes {
//release版本配置
release {
debuggable false
// 是否进行混淆
minifyEnabled true
//去除没有用到的资源文件,要求minifyEnabled为true才生效
shrinkResources true
// 混淆文件的位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.debug
//ndk的一些相关配置,也能够放到defaultConfig里面。
//指定要ndk须要兼容的架构(这样其余依赖包里mips,x86,arm-v8之类的so会被过滤掉)
ndk {
abiFilter "armeabi"
}
}
//debug版本配置
debug {
debuggable true
// 是否进行混淆
minifyEnabled false
//去除没有用到的资源文件,要求minifyEnabled为true才生效
shrinkResources true
// 混淆文件的位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.debug
//ndk的一些相关配置,也能够放到defaultConfig里面。
//指定要ndk须要兼容的架构(这样其余依赖包里mips,x86,arm-v8之类的so会被过滤掉)
ndk {
abiFilter "armeabi"
}
}
}
// lint配置
lintOptions {
//移除lint检查的error
abortOnError false
//禁止掉某些lint检查
disable 'NewApi'
}
}
复制代码
android中还能够有如下配置: productFlavors{ } 产品风格配置,ProductFlavor类型;testOptions{ } 测试配置,TestOptions类型; dexOptions{ } dex配置,DexOptions类型;packagingOptions{ } PackagingOptions类型;jacoco{ } JacocoExtension类型。 用于设定 jacoco版本;splits{ } Splits类型。java
- compile:咱们最经常使用的依赖,编译时提供并打包进apk
- provided:编译时提供但不打包进apk
- 在gradlew 3.0 中complie过时了,用implementation和api替代
- api = compile
- implemention:将该依赖隐藏在内部,而不对外部公开
- buildscript里面的那个是插件初始化环境用的,用于设定插件的下载仓库
- android 中是工程依赖的一些模块和远程library的下载仓库的
- exclude: 设置不编译指定的模块,排除指定模块的依赖
- transitive:用于自动处理子依赖项,默认为true,gradle自动添加子依赖项。设置为false排除全部的传递依赖
- force:强制设置某个模块的版本。
- 经过在buildTypes中配置minifyEnable来开启和关闭proguard
- 经过proguardFiles 来配置混淆参数与keep的内容
- 混淆的做用:
- 压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute)。
- 优化(Optimize):对字节码进行优化,移除无用的指令。
- 混淆(Obfuscate):使用a,b,c,d这样简短而无心义的名称,对类、字段和方法进行重命名。
- 预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。
dependencies {
//依赖最新的1.x版本
compile "org.codehaus.cargo:cargo-ant:1.+"
}
复制代码
- 在AndroidManifest.xml配置mete-data
<meta-data
android:name="UMENG_CHANNEL"
android:value="Channel_ID" />
复制代码
- 配置Flavors:
android {
productFlavors {
xiaomi {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
}
_360 {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
}
baidu {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
}
wandoujia {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
}
}
}
或者批量修改
android {
productFlavors {
xiaomi {}
_360 {}
baidu {}
wandoujia {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
复制代码
- 在APP内读取 mete-data 配置肯定渠道
- 而后用 ./gradlew assembleRelease 这条命令会把Product Flavor下的全部渠道的Release版本都打出来。
- 由于以上方法须要屡次编译,速度较慢,当渠道变多以后不适合多渠道打包
- 改进的方法1 : apk反编译后重写AndroidManifest文件,再从新编译签名
- 改进的方法2 : 若是在META-INF目录内添加空文件,能够不用从新签名应用。所以,经过为不一样渠道的应用添加不一样的空文件,能够惟一标识一个渠道
- 在采用V2签名后,以上方法再也不适用
- 考虑到V2签名的特色(对APK Signing Block是不进行验证的),咱们向V2签名后的APK签名区块写入渠道号,实现多渠道打包
由于v1签名能够在不改变签名状况下二次打包,咱们能够在gradle中对dex文件进行本身的签名android
- Android系统组件
- JNI
- 反射
- WebView的JS调用
- 内部类
- Annottation
- enum
- 范型
- 序列化
- 第三方
- 初始化阶段:会去读取根工程中setting.gradle中的include信息,决定有哪几个工程加入构建, 建立project实例,好比下面有三个工程: include ':app', ':lib1', ':lib2
- 配置阶段:,会去执行全部工程的build.gradle脚本,配置project对象,一个对象由多个任务组成, 此阶段也会去建立、配置task及相关信息。
- 运行阶段:根据gradle命令传递过来的task名称,执行相关依赖任务
经过配置productFlavors,将区别代码放置在对应的问价下,gradle会自动打出相应包git