由于想要验证Compose最新的debug特性,而我目前使用的版本(Dolphin 小海豚)不支持,查看官网说明需要最新版本,所以不得已进行了一下Android Studio版本升级,过程中遇到一些问题,本文仅做记录。(真是不想升级,一升级就是连锁反应,需要处理的东西太多了,折腾很久。。)
目前去官网下载最新的稳定版本是 Android Studio Flamingo | 2022.2.1 代号:Flamingo,中文名:火烈鸟。
发布日志请查看这里:https://developer.android.com/studio/releases
Android Studio 和 对应插件之间的对应关系:
注意这里的8.0就对应了工程根目录下build.gradle
中的com.android.application
和com.android.library
两个插件的版本号:
这里以前旧版本中的写法是 dependencies { classpath("com.android.tools.build:gradle:7.3.1") }
现在官方全部采用 plugins {id xxx}
的写法了。
Android 插件 和 对应最低Gradle版本要求之间的对应关系:
注意这里的Gradle版本就对应gradle/wrapper/gradle-wrapper.properties
中的版本:
这个包比较大,如果你的网比较好,就让AS帮你下,否则可以先到网上搜索一下自行下载好对应的zip包,然后放在C:\Users\用户名\.gradle\wrapper\dists
目录下(Windows用户,苹果同理)。这里可以先打开一下AS,然后看到AS显示正在下载gradle-8.0的提示就马上关闭。AS会在这个目录下生成缓存目录,然后你可以对照该目录下以前下载过的gradle版本,看它怎么放你就怎么放。再重新打开AS,它就会自动加载了,这是离线设置gradle包的方法。
使用 AGP 8.0 还有一些其他配置要求:
这里最关键的一点是对JDK版本的要求最低是 JDK 17,默认下载的Android Studio Flamingo 会打包自带 JDK 17 并且会自动配置,不需要自己另外下载和配置。但是一般情况下,你升级完肯定是有旧项目要使用新升级的AS打开的,这时旧项目中的JDK相关的配置,仍然需要手动修改,主要修改如下部分内容:
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
...
}
}
...
如果项目中有很多module都有这个配置,则需要全部修改,注意JDK 17是硬性要求,必须要修改。
如果不打算使用Flamingo自带的 JDK 17 ,那么需要自己电脑中独立安装JDK 17,配置好环境变量后,在AS中右键Open Module Settings或选择File->Project Structure按照下图配置:
以上版本对应关系均可以在这里找到:https://developer.android.com/build/releases/gradle-plugin
接下来就是 Compose Compiler 和 对应兼容的 Kotlin 版本之间的对应关系:
我这里选择的是1.4.3,因为我后面 Compose UI 的版本选的是1.4.3,我想保持一致,当然你可以选择更高的。
但是需要注意的是,这里我们需要根据Compose编译器的版本去选择对应的Kotlin版本,因为其实是这样的,我们需要指定的Compose编译器版本才能去编译指定的Compose UI 版本,而指定的Compose编译器版本需要兼容指定的Kotlin版本,所以其实是要先看你的Compose UI 是用的什么版本。但是总的来说高版本的Compose编译器肯定是能编译低版本的Compose UI的。
以上对应关系可以在这里找到:https://developer.android.com/jetpack/androidx/releases/compose-kotlin
接下来就是 Compose UI 版本的选择:
这个就比较简单了,目前 Compose UI 的稳定版本是1.4.3,所以前面 Compose Compiler 我选择的也是1.4.3,官方的配置是使用 Compose Compiler 1.4.7 + Compose UI 1.4.3,当然你可以选择按照官方的这种配置方案。
以上版本可以在这里找到:https://developer.android.com/jetpack/androidx/releases/compose-ui
然后我们可以在项目根目录下的build.gradle
中统一配置一下:
在app module模块中引用:
至于其他compose库的选择,可以参考这里,或者点击这里进行搜索,它们其实跟AS没有什么太大依赖关系了。
由于工程中有一些ksp的demo代码,所以需要更新KSP插件的版本,根据前面选择的kotlin版本到这个地方找对应的版本即可:https://github.com/google/ksp/releases,由于前面选择的kotlin版本是1.8.10,所以这里选择使用1.8.10-1.0.9的版本:
这个开始我没更新,但是同步gradle后报错,更新后正常。最新版本可以在这里获取:https://github.com/google/protobuf-gradle-plugin/releases,目前最新版本是v0.9.3
注意,如果你项目中有使用protobuf,且版本是 ≤ 0.9.1 的版本,请跳过 0.9.2,直接升级到 0.9.3+,因为 0.9.2版本有个bug,使用会编译报错,官方在0.9.3版本中修复了。(别问我怎么知道的)
app module的build.gradle中也需要参考官方配置(如果报错的话):https://github.com/google/protobuf-gradle-plugin,目前我的配置如下(运行正常没有报错):
// DataStore-protobuf
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.21.12"
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
// for more information.
generateProtoTasks {
all().configureEach { task ->
task.builtins {
java {
option 'lite'
}
kotlin {}
}
}
}
}
如果没有条件“科学上网”,可能下载一些库会比较慢,此时可以配置一下配置阿里云镜像解除封印,速度会快很多,主要是以下几个地址:
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/releases' }
maven { url 'https://maven.aliyun.com/repository/snapshots' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
修改settings.gradle
中pluginManagement
和dependencyResolutionManagement
中的repositories
内容为以上地址即可:
注意,以上地址如有变化访问不通可以参考这里获取最新地址:https://developer.aliyun.com/mvn/guide
如果 Compose compiler 和 kotlin 版本之间出现兼容问题,可能需要在dependencyResolutionManagement
的repositories
中添加如下地址:
maven {
// For kotlin Compose Compiler 有对应的兼容 kotlin版本
// check: https://github.com/jimgoog/ComposeAppUsingPrereleaseComposeCompiler#project-configuration
url "https://androidx.dev/storage/compose-compiler/repository/"
}
这是因为前面提到过的,Compose Compiler 有对应的兼容 kotlin版本,不能乱用,如果出现兼容问题可以参考这个地址解决。
接下终于就可以同步gradle了。。。
不出意外,同步完果然报错了。。首先发现的错误是代码中不能访问BuildConfig
类了,看来还是有需要调整兼容的地方要修改。。
这部分是官网列出来的,在 AGP 8.0 以上以下构建选项的默认值与之前有所不同
上表中前3个值是与应用代码比较相关的,这三个以前默认是开启的,使用 AGP 8.0 以后需要用户手动开启,否则默认是关闭的。尤其是第一个,也就是说现在默认不会生成BuildConfig
这个类了,哪个模块需要就在哪个模块中自行开启,因此需要在app module的build.gradle
中做如下修改:
android {
...
buildFeatures {
compose true
// Enable BuildConfig only for modules that need it. AGP 8.0 开始需要手动开启
buildConfig = true
// 以下需要的话同样需要手动开启
// aidl = true
// renderScript = true
}
}
...
这样就能在代码中访问到BuildConfig
类了。
上表中后3个值中我们需要关注的是关于R类的生成,在默认情况下对于库模块是不可传递的,这意味着每个R类只包含库模块本身声明的资源,而不是来自其依赖项的资源。
gradle.properties
文件中的nonTransitiveRClass
标志控制R类的行为。从 AGP 8.0 开始,它在未指定时默认值为 true
(不传递)。并且,在引用资源时必须使用 完全限定的命名空间 调用。
R类是将资源名称映射到代码中的 ID 的生成类。在 Android Studio Bumblebee / AGP 7.1 之前,R类是可传递的。这意味着构建不仅仅是为该库生成R类而是为该库所依赖的所有模块生成资源 ID。这一行为将导致体积更大的apk文件和更长的构建时间。
在非传递行为中,每个库模块R类仅包含模块本身声明的资源,从而减少了该模块R类的大小。
相比以前减少体积,加快构建速度,且不会出现同名R类资源覆盖问题(因为指定包名调用)。
提到R类,这里还有一个与R类相关的配置需要注意一下,虽然不是从AGP 8.0开始要求的,但是新版本中仍然是需要的:在gradle中指定namespace
属性作为资源命名空间,以替代AndroidManifest.xml
中的package
属性。在以前AndroidManifest.xml
中的package
同时承担了applicationId
和资源命名空间的角色,后来gradle中专门提供了一个applicationId
用作应用标识,现在,直接使用两个专门的属性applicationId
和namespace
分别表示应用标识和资源命名空间,更加明确了。
现在可以将package
属性从AndroidManifest.xml
删除了:
如果你使用 Android Studio Flamingo 运行 flutter 项目,可能会遇到与namespace
相关的问题,例如:
这个有可能是Flutter插件所使用的AGP与AGP 8.0 冲突导致的,已经有人在github上提出了这个已知问题:[add-to-app] error : Namespace not specified. Please specify a namespace in the module’s build.gradle
另外,从 AGP 8.0 开始,以下选项值默认值不能修改,它们默认被强制设置为true,即便你在gradle.properties
文件中声明,也会被忽略。
接下终于可以继续同步gradle了。。。
不过这次是一些Compose的代码报错,查看了一下基本上是一些api的变动,比如之前使用某个API需要添加实验性API的注解,现在注解报错,提示不存在了,说明该API转正了,那么直接将报错的注解删除即可。
如果是某个api方法不存在了、或方法参数改变了,这时需要查找对应的新版本的解决方法,不过好在 Compose UI虽然更新快,但是有更新日志:https://developer.android.com/jetpack/androidx/releases/compose-ui
比如下面这个报错了,不知道怎么正确实现,可以复制它,然后到上面的Compose UI Release Notes地址页面Ctrl+F搜索:
可以看到modifierElementOf
这个api确实被删除了,替代方案是使用继承ModifierNodeElement
类的方式,在AS找到ModifierNodeElement
类源码:
复制ModifierNodeElementSample
,然后到 https://cs.android.com/ 中搜索:
可以看到这里就能找到关于该类如何使用的官方的示例代码。其他报错Api可以参考这个方式查找,如果实在找不到,只能Google搜索一下了。
修复完相关代码报错后继续运行。。。
这次报了一个aar库找不到的错误:
这个错误非常奇怪,而且不是总是出现,它说在这个地址:https://maven.aliyun.com/repository/central/com/github/skydoves/landscapist/2.1.1/landscapist-2.1.1.aar 中 Could not find landscapist-2.1.1.aar
,但实际上是可以访问到的,甚至能直接点击链接下载下来。不知道为什么,可能阿里云同步的文件有问题?无奈,我只能把settings.gradle
中dependencyResolutionManagement
的repositories里将mavenCentral()
加了回去:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral() // 不加这个提示阿里云的地址找不到landscapist-2.1.1.aar
// 阿里云镜像
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/releases' }
maven { url 'https://maven.aliyun.com/repository/snapshots' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
}
}
但是加了mavenCentral()
有可能国内的网访问很慢或者下载不到这个aar有可能需要科学上网。
加这个之后,就运行成功了。。真的不容易。。
AGP 8.0.0-alpha09 引入了新的settings设置插件。设置插件可让您将全局配置(适用于所有模块的配置)集中在一个地方,这样您就无需在多个模块中复制和粘贴配置。此外,您可以使用设置插件来创建工具 执行配置文件,或关于如何运行工具的不同说明,并在它们之间切换。(官方终于知道要搞一个这个了,真是后知后觉,民间不知道搞了多少年了。。)
注意:设置插件目前只能在 Groovy 中使用。
要使用设置插件,请在settings.gradle
文件中应用该插件:
apply plugin 'com.android.settings'
集中全局配置
要配置Global全局配置,请使用settings.gradle
文件中的 android {}
新块。这是一个例子:
android {
compileSdk 31
minSdk 28
...
}
但以上配置我尝试未能成功,在settings.gradle
中添加apply plugin 'com.android.settings'
报错不被识别,原因未知,如果有尝试成功的请留言告知。
可以参考:https://developer.android.com/build/build-variants
最后再吐槽一下,Android官方也没有一个Android Studio升级的指南清单,每次都是自己遇到问题一个一个的现查现卖,每次升级都是大型车祸现场,简直不要太惨了。。