Compose 与 AGP、KGP 的关系

简介: Compose 与 AGP、KGP 的关系

在学习 Compose 的时候,有没有同学有一种困惑,Compose 到底是哪个 AGP 版本开始支持的,然后还会听到一些声音说,Compose 从 AGP 7.x 才开始支持,可当我使用 IntelliJ IDEA 创建 KMP 项目时,AGP 版本明明是 4.2.2,所以,为了搞清楚这个问题,我准备探索下 Compose 与他们之间的关系。


如果反编译过 Compose 项目的想必都知道,@Composable 注解下的方法会被生成各种 $composer 代码,那这块代码是谁来生成的呢?如果看过官方文档的话,是可以看到有一个叫 Compose Compiler 库,他的主要目的借助 Kotlin 编译器插件,转换可组合函数(@Composable)并实现优化:


image.png

但如果你仔细去看 Compose 项目的话,怎么找都找不到这个依赖在哪,是不是很气?没关系,我们打印一下依赖树看看,是不是被谁给加进去了:


kotlin-extension - Configuration for Compose related kotlin compiler extension
\--- androidx.compose.compiler:compiler:1.1.1
复制代码


诶,还真找到了,然后继续找 configurations 创建 kotlin-extension 的地方,在 AGP 的 TaskManager 里面找到了:


image.png


再想想,借助 Kotlin 编译插件来实现各种魔法的除了 Compose 还有谁?想必大家已经猜到了,就是被标记淘汰的 kotlin-android-extensions,刚开始用的时候,确实省了很多 findViewById 的操作。 那么,这么多的魔法操作,在整个项目中的架构关系和依赖关系到底是什么样的呢?


架构梳理


江同学在他的博文中贴了一张插件架构图,很清晰的展现了 AGP、KGP、Extension 的分层:

image.png

Compose Compiler 属于  Extension 这个层级,那他们是怎么参与 KGP 编译的呢?那就是 SPI,可以看下各个库的声明:


依赖图
kotlin-android-extensions

image.png

compose.compiler

image.pngimage.png

霍老师的 Kotlin-Trim-Indent

image.png

KGP 会通过 serviceLoader 加载所有的 CommandLineProcessor 和 ComponentRegistrar 参与 KCP 编译:

image.png

依赖梳理


现在我们已经知道了 Compose 是怎么参与 KGP 编译的了,那么,他们的依赖关系是什么样的呢?我画个图:

image.png


  • Compose Compiler 是被 AGP 依赖进去的,这也是困扰大家 Compose 与 AGP 版本到底是怎么配置的主要原因
  • KGP 的 pom.xml 将 kotlin-android-extension 依赖进来,所以,版本跟随 KGP
  • TGP 是霍老师的插件,直接在 build.gradle 通过 classpath 引入

一点疑惑:

  • compose compiler 为啥不做成单独插件呢?这样就可以从 AGP 里面剥离出来,通过 classpath 直接引入来减少版本困扰,现在改个 Compose 版本需要涉及 KGP 和 AGP
  • KGP 主要是 KCP 编译相关的东西,为啥又要将 android  相关的 kotlin-android-extension 放进 KGP 依赖进来呢?

解决 Compose 版本问题


虽然 Compose 会涉及到 KGP 和 AGP,但 AGP 还是很贴心的,提供了 extension 来设置 Compose 与 KCP 的版本,具体可以看 AGP 的 TaskManager 类:


image.png

从 TaskManager 来看,AGP 仅仅只是帮我们添加了 compose-compiler 和 KCP 依赖而已,这两个依赖版本号是可以通过 composeIOptions 来配置,如果没配置,则使用 AGP 内置写死的版本(很多人就是因为这个写死的版本导致 compose 配置不起来)

需要注意的是,KCP 的版本最好设置一下,不然,会强制 force 使用 AGP 内部配置的版本


所以,我们的项目可以改造成:


项目下的 build.gradle


buildscript {
   ext.kotlin_version = '1.6.10'
   ext.compose_version = '1.1.0'
   ...
   dependencies {
      ...
      classpath 'com.android.tools.build:gradle:4.2.2'
      classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
   }
}
复制代码

app 模块下的 build.gradle

android {
    ...
    buildFeatures{
        compose true
    }
    composeOptions{
        // 1、
        kotlinCompilerVersion  "$compose_version"
        // 2、
        kotlinCompilerExtensionVersion  "$kotlin_version"
    } 
}
dependencies {
   implementation "androidx.compose.ui:ui:$compose_version"
   ...
}
复制代码

主要看 composeOptions 的设置:

  1. kotlinCompilerVersion  :   指定 Compose Compiler 版本,与 Compose 版本保持一致
  2. kotlinCompilerExtensionVersion :指定 kotlin 的编译版本(KCP),与 kotlin-gradle-plugin 版本保持一致

其实,AGP 对 Compose 的影响仅仅只作用于 TaskManager 中是否有无添加 compose-compiler 依赖,如果 AGP 有,则 Compose 与 AGP 版本无关。所以,大家如果想了解自己老项目是否能直接接入 Compose ,可以看下自己项目的 AGP 版本,然后看下这个版本的 TaskManager 源码,目前我查看的 AGP 4.1.0 版本是有的。笔者的项目是 4.2.2 的 AGP ,已成功接入 Compose 1.1.0 版本并跑起来。

这里面唯一有关系的是 KCP 版本与 Compose-Compiler 版本,但 KCP 是被 KGP 引用进来的,所以,我们又可以简单的认为是 KGP 与 Compose 有关系,在上述配置的 composeOptions 代码块中,就是配置的这两个版本,这两个版本的关系官方文档也给出了,我列出几个主要版本的关系,具体的可以看官方文档《Compose 与 Kotlin 的兼容性对应关系 》:

Compose Compiler 版本 兼容的 Kotlin 版本
1.2.0-rc01 1.6.21
1.1.1 1.6.10
1.1.0 1.6.10
1.0.5 1.5.31
1.0.4 1.5.31
1.0.3 1.5.30
1.0.2 1.5.21
1.0.1 1.5.21
1.0.0 1.5.10

总结


现在,终于理解了版本这层关系,所以,接下来你是否已经对 kotlin-android-extensioncompose-compiler是怎么生成代码而蠢蠢欲动了呢

目录
相关文章
|
Ubuntu Linux
Linux Ubuntu系统 OpenVPN 客户端安装
Linux Ubuntu系统 OpenVPN 客户端安装
Linux Ubuntu系统 OpenVPN 客户端安装
|
人工智能 达摩院 并行计算
中文语音识别转文字的王者,阿里达摩院FunAsr足可与Whisper相颉顽
君不言语音识别技术则已,言则必称Whisper,没错,OpenAi开源的Whisper确实是世界主流语音识别技术的魁首,但在中文领域,有一个足以和Whisper相颉顽的项目,那就是阿里达摩院自研的FunAsr。 FunAsr主要依托达摩院发布的Paraformer非自回归端到端语音识别模型,它具有高精度、高效率、便捷部署的优点,支持快速构建语音识别服务,最重要的是,FunASR支持标点符号识别、低语音识别、音频-视觉语音识别等功能,也就是说,它不仅可以实现语音转写,还能在转写后进行标注,一石二鸟。
中文语音识别转文字的王者,阿里达摩院FunAsr足可与Whisper相颉顽
|
网络协议 安全 Linux
Tool之wget:wget的简介、安装、入门、使用方法之详细攻略(一)
Tool之wget:wget的简介、安装、入门、使用方法之详细攻略
Tool之wget:wget的简介、安装、入门、使用方法之详细攻略(一)
|
算法 数据安全/隐私保护
一文详解 RSA 非对称加密算法
非对称加密算法指的是 加、解密使用不同的密钥,一把为公开的公钥,另一把为私钥。 公钥加密的内容只能由私钥进行解密,反之由私钥加密的内容只能由公钥进行解密。也就是说,这一对公钥、私钥都可以用来加密和解密,并且一方加密的内容只能由对方进行解密。
10060 1
|
9月前
|
Java API Apache
java集成stable diffusion
通过REST API和JNI两种方法,我们可以在Java应用程序中集成Stable Diffusion模型。REST API方法更加简单和易于维护,而JNI方法则提供更高的性能。根据具体应用场景和需求,选择合适的集成方法,可以充分利用Stable Diffusion的强大功能,实现高效的图像生成和处理。
228 15
|
API
【Qt 学习笔记】QWidget的toolTip属性 | focusPolicy属性
【Qt 学习笔记】QWidget的toolTip属性 | focusPolicy属性
844 5
|
11月前
|
SQL 存储 关系型数据库
【赵渝强老师】Hive的内部表与外部表
Hive是基于HDFS的数据仓库,支持SQL查询。其数据模型包括内部表、外部表、分区表、临时表和桶表。本文介绍了如何创建和使用内部表和外部表,提供了详细的步骤和示例代码,并附有视频讲解。
740 1
|
Java Android开发 Windows
使用keytool查看Android APK签名
本文介绍了如何使用Windows命令行工具和keytool查看APK的签名信息,并提供了使用AOSP环境中的signapk.jar工具对APK进行系统签名的方法。
1503 0
使用keytool查看Android APK签名
深入了解 Jetpack Compose 中的 Modifier
深入了解 Jetpack Compose 中的 Modifier
378 0
【Qt 学习笔记】Qt窗口 | 标准对话框 | 文件对话框QFileDialog
【Qt 学习笔记】Qt窗口 | 标准对话框 | 文件对话框QFileDialog
2973 4