目录
- 在Android Studio 3.0下创建项目使用Kotlin
- Gradle统一依赖版本
- Gradle 3.x依赖的变化
- 介绍
- 为什么做出修改
- 新Gradle 3.x带来的解决方案
- Gradle关键字变化
- 个人习惯之项目创建后的配置
- Android Stuido 3.0 的坑
- ADB 端口被占用
- 应用过大编译堆溢出
在Android Studio 3.0下创建项目使用Kotlin
使用Kotlin
Gradle统一依赖版本
- 创建
config.gradle
文件在根目录
ext {
android = [
compileSdkVersion: 26,
buildToolsVersion: "26.0.2",
minSdkVersion : 19,
targetSdkVersion : 26
]
dependencies = [
kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version",
appcompatv7 : 'com.android.support:appcompat-v7:26.0.0-alpha1',
constraintlayout: 'com.android.support.constraint:constraint-layout:1.0.2'
]
}
- 文件
Project Gradle
中引入上面创建config.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "config.gradle"
- 配置
Module Gradle
//(a) 引入对应的集合
def config = rootProject.ext.android
def libs = rootProject.ext.dependencies
······
//(b)使用android集合的参数
minSdkVersion config.minSdkVersion
targetSdkVersion config.targetSdkVersion
······
//(c)使用dependencies集合的参数,因为使用了高版本的Gradle tool,所以不在是使用complie关键字进行依赖导入
implementation libs.kotlin
implementation libs.appcompatv7
implementation libs.constraintlayout
Gradle 3.x依赖的变化
介绍
2017 年google 后,Android studio
版本更新至3.0
,更新中,连带着com.android.tools.build:gradle
工具也升级到了3.0.0
,在3.0.0
中使用了最新的Gralde 4.0
里程碑版本作为gradle
的编译版本,该版本gradle编译速度有所加速,更加欣喜的是,完全支持Java8
。当然,对于Kotlin
的支持,在这个版本也有所体现,Kotlin
插件默认是安装的。
在com.android.tools.build:gradle 3.0
以下版本依赖在gradle
中的声明写法:
compile fileTree(dir: 'libs', include: ['*.jar'])
但在3.0后的写法为:
implementation fileTree(dir: 'libs', include: ['*.jar'])
//或
api fileTree(dir: 'libs', include: ['*.jar'])
在3.0版本中,compile 指令被标注为过时方法,而新增了两个依赖指令,一个是implement 和api,这两个都可以进行依赖添加,但是有什么区别呢?
为什么做出修改
简单的说为了加快工程的构建。
为了理解老版本Gradle plugin 2.0构建系统的限制,这里假设有个工程使用了多层module依赖方式。请看下图。
对于最底部的基础module
,其将会有两种可能的变化:
-
Implementation
变化:不会改动本module
对外暴露的接口。 -
Application binary interface (ABI)
变化:将会改变本module
对外暴露的接口。(本module
指的是调用dependency
的module
)
注意,所有需要重新编译的module将会在以下用红色标出。
在Gradle plugin 3.x(新版本)中:
- Implementation 变化
当本module依赖的ib(也可以是module)发生变化时,由于本module对外暴露的接口并不发生变化,在构建工程时gradle将会只重新编译本module,所有依赖于本module的module并不会发生编译。这种情况是没什么问题的。如图所示。
- ABI变化(Gradle 2.0 就是这种方式)
当本module依赖的ib(也可以是module)发生变化时,本module向外暴露的接口发生了变化,那么所有直接依赖于本module的module将不得不重新编译。
接下来,这些上层module可能通过其本身的接口对外暴露了底层module的部分内容,即意味着本module暴露的接口也发生了变化,这会使得依赖于上层module的上上层module也需要重新编译。这就导致了一个连锁效应,因此,为了绝对的安全起见,gradle将不得不重新编译整个工程,使得编译时间变得较长。如图所示。
那么重点来了:一点代码的改动可能会引起整个工程的重新编译,这将是多么悲催,而实际上我们之前的gradle插件2.0版本系列的确如此,根本原因就是gradle压根不知道暴露的接口可以通过一个接一个的依赖传递影响整个工程。
新Gradle 3.x带来的解决方案
最新版的Gradle plugin
需要你指出一个module
的接口是否对外暴露其依赖lib的接口。基于此,可以让项目构建时,gradle
可以判断哪个需要重新编译。因此,老版本的构建关键字compile被废弃了,而是改成了这两个:
- api:同compile作用一样,即认为本module将会泄露其依赖的module的内容。
- implementation:本module不会通过自身的接口向外部暴露其依赖module的内容。 由此,我们可以明确的告诉gradle去重新编译一个module,若是这个使用的module的接口发生变化的话。
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation libs.kotlin
// 当appcompatv7发生变化时,只是重新编译本module
implementation libs.appcompatv7
// 当constraintlayout发生变化时,需要重新编译本module以及所有使用本module的module
api libs.constraintlayout
//Test units
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
Gradle关键字变化
- compile -> api
所以更好的方式就是使用implementation来进行依赖,这会大大改善工程的构建时间。只有你明确要向外部暴露所依赖lib的接口时,才需要使用api依赖,整体来说,会减少很多重新编译。这一点,在官方指南中说的比较明确。 - provided -> compileOnly
- apk -> runtimeOnly
个人习惯之项目创建后的配置
- 勾选Kotlin
- 拷贝
config.gradle
文件到项目根目录 - 在项目
build.gradle
文件加入apply from: "config.gradle"
- 配置模块对应的
build.gradle
文件。
//(a) 引入对应的集合
def config = rootProject.ext.android
def libs = rootProject.ext.dependencies
······
//(b)使用android集合的参数
minSdkVersion config.minSdkVersion
targetSdkVersion config.targetSdkVersion
······
//(c)使用dependencies集合的参数,因为使用了高版本的Gradle tool,所以不在是使用complie关键字进行依赖导入
implementation libs.kotlin
implementation libs.appcompatv7
implementation libs.constraintlayout
- 编辑
Android Stuido 3.0 的坑
错误一
Log 信息
\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values\values.xml
Error:(232) resource android:attr/fontStyle not found.
Error:(232) resource android:attr/font not found.
Error:(232) resource android:attr/fontWeight not found.
解决方案
检查 buildToolsVersion
和 compileSdkVersion
是否对得上。
ADB 端口被占用
电脑安装了 PP助手,它会占用 adb 的端口,导致 Android Studio 不能使用 adb。
Unable to create Debug Bridge: Unable to start adb server: error: could not install *smartsocket* listener: cannot bind to 127.0.0.1:5037: Only one usage of each socket address (protocol/network address/port) is normally permitted. (10048)
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
error: unknown host service
could not read ok from ADB Server
* failed to start daemon *
error: cannot connect to daemon
'D:\Software\Android\sdk\platform-tools\adb.exe start-server' failed -- run manually if necessary
解决方法
根据提示查看adb的端口号5037被谁占用:
netstat -aon|findstr “5037”
找到该 PID 对应的进程,杀死即可。
应用过大编译堆溢出
Gradle build failing - Java Heap Space
原因是应用资源文件太大,打包 apk 时内存不够用。
解决方案
只需要修改 gradle.properties
文件。以下修改为分配4G的堆内存。
org.gradle.jvmargs=-Xmx4096m