6.6.3 - Alpha3 - Gradle 构建脚本提升版本自适应能力 (discussion #369)

This commit is contained in:
SuperMonster003
2025-05-13 18:49:00 +08:00
parent 94122476fa
commit adf8dc9f30
22 changed files with 429 additions and 240 deletions

View File

@@ -1,7 +1,7 @@
{ {
"$data": { "$data": {
"v6.6.3": { "v6.6.3": {
"released_date": "2025/05/09", "released_date": "2025/05/13",
"feature": [ "feature": [
"版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据", "版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据",
"timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态", "timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态",
@@ -30,7 +30,8 @@
"打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_", "打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_",
"已忽略更新记录及客户端模式连接地址记录支持清空操作", "已忽略更新记录及客户端模式连接地址记录支持清空操作",
"版本更新信息支持多语言显示 (与当前显示语言同步)", "版本更新信息支持多语言显示 (与当前显示语言同步)",
"使用异步加载方式一定程度提升文件管理器列表滑动流畅性" "使用异步加载方式一定程度提升文件管理器列表滑动流畅性",
"Gradle 构建脚本提升版本自适应能力 _[`discussion #369`](http://discussions.autojs6.com/369)_"
], ],
"dependency": [ "dependency": [
"本地化 Material Dialogs 版本 0.9.6.0", "本地化 Material Dialogs 版本 0.9.6.0",
@@ -38,7 +39,7 @@
"附加 Jsoup 版本 1.19.1", "附加 Jsoup 版本 1.19.1",
"附加 Material Progressbar 版本 1.4.2", "附加 Material Progressbar 版本 1.4.2",
"附加 Flexmark Java HTML to Markdown 版本 0.64.8", "附加 Flexmark Java HTML to Markdown 版本 0.64.8",
"升级 Gradle 版本 8.14-rc-1 -> 8.14-rc-2", "升级 Gradle 版本 8.14-rc-1 -> 8.14",
"升级 Androidx Room 版本 2.7.0 -> 2.7.1" "升级 Androidx Room 版本 2.7.0 -> 2.7.1"
] ]
}, },

View File

@@ -389,7 +389,7 @@ SDK Tools (أدوات SDK) (في النافذة اليمنى)
يعتمد مشروع AutoJs6 على إصدار `JDK (مجموعة تطوير جافا)` بإصدار لا يقل عن `17`، ولكن يفضل الإصدار الذي لا يقل عن `19`. يعتمد مشروع AutoJs6 على إصدار `JDK (مجموعة تطوير جافا)` بإصدار لا يقل عن `17`، ولكن يفضل الإصدار الذي لا يقل عن `19`.
اعتبارًا من 2 May 2025، الإصدار الأقصى المدعوم من JDK لمشروع AutoJs6 هو `24`. اعتبارًا من 13 May 2025، الإصدار الأقصى المدعوم من JDK لمشروع AutoJs6 هو `24`.
> ملاحظة: إذا كان نظام الكمبيوتر يحتوي على JDK والإصدار يفي بالمتطلبات المذكورة أعلاه، فيمكنك تخطي هذا القسم. > ملاحظة: إذا كان نظام الكمبيوتر يحتوي على JDK والإصدار يفي بالمتطلبات المذكورة أعلاه، فيمكنك تخطي هذا القسم.

View File

@@ -389,7 +389,7 @@ Check `Show Package Details`, click NDK and CMake respectively to ensure the cor
The `JDK (Java Development Kit)` version required for the AutoJs6 project should be at least `17`, but `19` or higher is recommended. The `JDK (Java Development Kit)` version required for the AutoJs6 project should be at least `17`, but `19` or higher is recommended.
As of May 2, 2025, AutoJs6 supports up to version `24` of the JDK. As of May 13, 2025, AutoJs6 supports up to version `24` of the JDK.
> Note: If the JDK is already installed on the computer system and the version meets the above requirements, this section can be skipped. > Note: If the JDK is already installed on the computer system and the version meets the above requirements, this section can be skipped.

View File

@@ -389,7 +389,7 @@ Marca `Show Package Details (Mostrar detalles del paquete)`, haz clic en NDK y C
La versión mínima requerida del `JDK (Kit de Desarrollo de Java)` para el proyecto AutoJs6 es `17`, pero se recomienda usar una versión no inferior a `19`. La versión mínima requerida del `JDK (Kit de Desarrollo de Java)` para el proyecto AutoJs6 es `17`, pero se recomienda usar una versión no inferior a `19`.
Hasta el 2 de May de 2025, AutoJs6 soporta hasta la versión `24` de JDK. Hasta el 13 de May de 2025, AutoJs6 soporta hasta la versión `24` de JDK.
> Nota: Si el sistema ya tiene instalado JDK y cumple con los requisitos anteriores, puedes omitir esta sección. > Nota: Si el sistema ya tiene instalado JDK y cumple con los requisitos anteriores, puedes omitir esta sección.

View File

@@ -389,7 +389,7 @@ Cochez `Show Package Details (afficher les détails du package)`, puis cliquez r
La version de JDK (Kit de développement Java) requise pour le projet AutoJs6 doit être au moins `17`, mais il est recommandé d'avoir au moins `19`. La version de JDK (Kit de développement Java) requise pour le projet AutoJs6 doit être au moins `17`, mais il est recommandé d'avoir au moins `19`.
À partir du 2 May 2025, AutoJs6 prend en charge la version maximale de JDK `24`. À partir du 13 May 2025, AutoJs6 prend en charge la version maximale de JDK `24`.
> Note : Si le JDK est déjà installé sur le système informatique et que la version répond aux exigences ci-dessus, vous pouvez ignorer cette section. > Note : Si le JDK est déjà installé sur le système informatique et que la version répond aux exigences ci-dessus, vous pouvez ignorer cette section.

View File

@@ -389,7 +389,7 @@ SDK Tools (SDK ツール) (右側のウィンドウにあります)
AutoJs6プロジェクトが依存する `JDK (Java開発キット)` のリリースバージョンは少なくとも `17` で, それ以下のバージョンは推奨されませんが, 最低でも `19` の使用を推奨します. AutoJs6プロジェクトが依存する `JDK (Java開発キット)` のリリースバージョンは少なくとも `17` で, それ以下のバージョンは推奨されませんが, 最低でも `19` の使用を推奨します.
2025 年 5 月 2 日 現在, AutoJs6がサポートする最大のJDKバージョンは `24` です. 2025 年 5 月 13 日 現在, AutoJs6がサポートする最大のJDKバージョンは `24` です.
> 注: コンピュータシステムに適切なバージョンのJDKがインストールされている場合, この節の内容をスキップできます. > 注: コンピュータシステムに適切なバージョンのJDKがインストールされている場合, この節の内容をスキップできます.

View File

@@ -389,7 +389,7 @@ SDK Tools (SDK 도구) (오른쪽 창에 위치)
AutoJs6 프로젝트는 `JDK (Java 개발 도구 키트)` 버전이 `17` 이상이어야 하지만, `19` 이상을 권장합니다. AutoJs6 프로젝트는 `JDK (Java 개발 도구 키트)` 버전이 `17` 이상이어야 하지만, `19` 이상을 권장합니다.
2025 년 5 월 2 일 기준으로, AutoJs6이 지원하는 최대 JDK 버전은 `24`입니다. 2025 년 5 월 13 일 기준으로, AutoJs6이 지원하는 최대 JDK 버전은 `24`입니다.
> 메모: 시스템에 JDK가 설치되어 있고, 버전이 위의 요구 사항을 충족하는 경우, 이 섹션을 건너뛸 수 있습니다. > 메모: 시스템에 JDK가 설치되어 있고, 버전이 위의 요구 사항을 충족하는 경우, 이 섹션을 건너뛸 수 있습니다.

View File

@@ -389,7 +389,7 @@ SDK Tools (SDK Инструменты) (находится в правом ок
Для проекта AutoJs6 требуется версия `JDK (Java Development Kit)` не ниже `17`, но рекомендуется не ниже `19`. Для проекта AutoJs6 требуется версия `JDK (Java Development Kit)` не ниже `17`, но рекомендуется не ниже `19`.
По состоянию на 2 May 2025 года AutoJs6 поддерживает JDK максимальной версии `24`. По состоянию на 13 May 2025 года AutoJs6 поддерживает JDK максимальной версии `24`.
> Примечание: Если на компьютере уже установлен JDK и версия соответствует указанным требованиям, этот раздел можно пропустить. > Примечание: Если на компьютере уже установлен JDK и версия соответствует указанным требованиям, этот раздел можно пропустить.

View File

@@ -157,23 +157,33 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开
# v6.6.3 # v6.6.3
###### 2025/05/02 ###### 2025/05/13
* `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据
* `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态
* `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件
* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_
* `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题
* `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题
* `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题
* `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题
* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题
* `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题
* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题
* `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_ * `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_
* `修复` 使用 JavaAdapter 时导致 ClassLoader 调用栈溢出的问题 _[`issue #376`](http://issues.autojs6.com/376)_
* `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_ * `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_
* `修复` README.md 中部分语言日期格式不正确的问题 * `修复` README.md 中部分语言日期格式不正确的问题
* `优化` 关于应用与开发者页面增加水平布局适配 * `优化` 主题色扩充适配范围并支持更多控件类型
* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性
* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配
* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项
* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏
* `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_ * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_
* `优化` 已忽略更新记录及客户端模式连接地址记录支持清空操作
* `优化` 版本更新信息支持多语言显示 (与当前显示语言同步) * `优化` 版本更新信息支持多语言显示 (与当前显示语言同步)
* `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性 * `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性
* `优化` Gradle 构建脚本提升版本自适应能力 _[`discussion #369`](http://discussions.autojs6.com/369)_
* `优化` 部分依赖或本地库版本调整 _[`CHANGELOG.md`](http://project.autojs6.com/blob/master/app/src/main/assets-app/doc/CHANGELOG.md#v663)_ * `优化` 部分依赖或本地库版本调整 _[`CHANGELOG.md`](http://project.autojs6.com/blob/master/app/src/main/assets-app/doc/CHANGELOG.md#v663)_
# v6.6.2 # v6.6.2
@@ -320,7 +330,7 @@ SDK Tools (SDK 工具) (位于右侧窗口)
AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`. AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`.
截至 2025 年 5 月 2 日, AutoJs6 可支持 JDK 最高版本为 `24`. 截至 2025 年 5 月 13 日, AutoJs6 可支持 JDK 最高版本为 `24`.
> 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容. > 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容.

View File

@@ -389,7 +389,7 @@ SDK Tools (SDK 工具) (位於右側窗口)
AutoJs6 項目依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`. AutoJs6 項目依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`.
截至 2025 年 5 月 2 日, AutoJs6 可支持 JDK 最高版本為 `24`. 截至 2025 年 5 月 13 日, AutoJs6 可支持 JDK 最高版本為 `24`.
> 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容. > 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容.

View File

@@ -389,7 +389,7 @@ SDK Tools (SDK 工具) (位於右側視窗)
AutoJs6 專案依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`. AutoJs6 專案依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`.
截至 2025 年 5 月 2 日, AutoJs6 可支援 JDK 最高版本為 `24`. 截至 2025 年 5 月 13 日, AutoJs6 可支援 JDK 最高版本為 `24`.
> 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容. > 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容.

View File

@@ -157,23 +157,33 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开
# v6.6.3 # v6.6.3
###### 2025/05/02 ###### 2025/05/13
* `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据
* `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态
* `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件
* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_
* `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题
* `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题
* `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题
* `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题
* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题
* `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题
* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题
* `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_ * `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_
* `修复` 使用 JavaAdapter 时导致 ClassLoader 调用栈溢出的问题 _[`issue #376`](http://issues.autojs6.com/376)_
* `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_ * `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_
* `修复` README.md 中部分语言日期格式不正确的问题 * `修复` README.md 中部分语言日期格式不正确的问题
* `优化` 关于应用与开发者页面增加水平布局适配 * `优化` 主题色扩充适配范围并支持更多控件类型
* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性
* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配
* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项
* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏
* `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_ * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_
* `优化` 已忽略更新记录及客户端模式连接地址记录支持清空操作
* `优化` 版本更新信息支持多语言显示 (与当前显示语言同步) * `优化` 版本更新信息支持多语言显示 (与当前显示语言同步)
* `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性 * `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性
* `优化` Gradle 构建脚本提升版本自适应能力 _[`discussion #369`](http://discussions.autojs6.com/369)_
* `优化` 部分依赖或本地库版本调整 _[`CHANGELOG.md`](http://project.autojs6.com/blob/master/app/src/main/assets-app/doc/CHANGELOG.md#v663)_ * `优化` 部分依赖或本地库版本调整 _[`CHANGELOG.md`](http://project.autojs6.com/blob/master/app/src/main/assets-app/doc/CHANGELOG.md#v663)_
# v6.6.2 # v6.6.2
@@ -320,7 +330,7 @@ SDK Tools (SDK 工具) (位于右侧窗口)
AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`. AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`.
截至 2025 年 5 月 2 日, AutoJs6 可支持 JDK 最高版本为 `24`. 截至 2025 年 5 月 13 日, AutoJs6 可支持 JDK 最高版本为 `24`.
> 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容. > 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容.

View File

@@ -732,7 +732,7 @@ android {
// Configures multiple APKs based on ABI. // Configures multiple APKs based on ABI.
abi { abi {
// Enables building multiple APKs per ABI. // Enables building multiple APKs per ABI.
isEnable = /* isNotAssembleInrt */ !gradle.startParameter.taskNames.any { isEnable = /* isNotAssembleInrt */ gradle.startParameter.taskNames.none {
it.contains(Regex("^(:?$flavorNameApp:)?$buildActionAssemble$flavorNameInrt", IGNORE_CASE)) it.contains(Regex("^(:?$flavorNameApp:)?$buildActionAssemble$flavorNameInrt", IGNORE_CASE))
} }
// By default, all ABIs are included, so use reset() and include to specify that we only // By default, all ABIs are included, so use reset() and include to specify that we only
@@ -847,14 +847,29 @@ class Versions(filePath: String) {
private var javaVersionInfoSuffix = "" private var javaVersionInfoSuffix = ""
val javaVersion: JavaVersion by lazy { val javaVersion: JavaVersion by lazy {
var niceVersionInt = javaVersionRaw.toInt() var javaVersionInt = determineJavaVersion()
gradle.beforeProject {
extensions.extraProperties["javaVersion"] = javaVersionInt
}
JavaVersion.toVersion(javaVersionInt)
}
private fun determineJavaVersion(): Int {
if (gradle.extra.has("javaVersionOverriddenByUser")) {
(gradle.extra.get("javaVersionOverriddenByUser") as? Int)?.let {
javaVersionInfoSuffix += " [user-specified]"
return it
}
}
var versionInt = javaVersionRaw.toInt()
var isFallback = false var isFallback = false
while (niceVersionInt > javaVersionMinSupported) { while (versionInt > javaVersionMinSupported) {
if (JvmTarget.values().any { it.name.contains(Regex("_$niceVersionInt$")) }) { if (JvmTarget.values().any { it.name.contains(Regex("_$versionInt$")) }) {
break break
} }
niceVersionInt -= 1 versionInt -= 1
isFallback = true isFallback = true
} }
@@ -862,26 +877,20 @@ class Versions(filePath: String) {
javaVersionInfoSuffix += " [fallback]" javaVersionInfoSuffix += " [fallback]"
} }
if (gradle.extra.has("gradleVersionToCoerceJavaVersion")) { if (versionInt > currentVersionInt) {
(gradle.extra["gradleVersionToCoerceJavaVersion"] as? String)?.let { versionInt = currentVersionInt
val maxGradleVersion = getMaxSupportedJavaVersion(it) javaVersionInfoSuffix += " [consistent-downgraded]"
if (niceVersionInt > maxGradleVersion) { }
niceVersionInt = maxGradleVersion
javaVersionInfoSuffix += " [coerced]" if (gradle.extra.has("javaVersionCoercedByGradle")) {
(gradle.extra["javaVersionCoercedByGradle"] as? Int)?.let {
if (versionInt > it) {
versionInt = it
javaVersionInfoSuffix += " [coercive-gradle-downgraded]"
} }
} }
} }
return versionInt
if (niceVersionInt > currentVersionInt) {
niceVersionInt = currentVersionInt
javaVersionInfoSuffix += " [consistent]"
}
gradle.beforeProject {
extensions.extraProperties["javaVersion"] = niceVersionInt
}
JavaVersion.toVersion(niceVersionInt)
} }
private var isBuildNumberAutoIncremented = false private var isBuildNumberAutoIncremented = false
@@ -962,51 +971,6 @@ class Versions(filePath: String) {
properties.store(file.writer(), null) properties.store(file.writer(), null)
} }
private fun getMaxSupportedJavaVersion(gradleVersion: String): Int {
/* https://docs.gradle.org/current/userguide/compatibility.html . */
val presetVersionMap = listOf(
17 to "7.3",
18 to "7.5",
19 to "7.6",
20 to "8.3",
21 to "8.5",
22 to "8.8",
23 to "8.10",
24 to "8.11", /* Unofficial as of Mar 19, 2025. */
)
fun parseVersion(version: String) = version.split(Regex("[.-]")).map { it.toIntOrNull() ?: 0 }
val inputGradleVersionInts = parseVersion(gradleVersion)
var maxJavaVersion: Int = presetVersionMap.first().first
for ((presetJavaVersion, presetGradleVersion) in presetVersionMap) {
val presetGradleVersionInts: List<Int> = parseVersion(presetGradleVersion)
for (i in presetGradleVersionInts.indices) {
when {
i > inputGradleVersionInts.lastIndex -> {
break
}
inputGradleVersionInts[i] > presetGradleVersionInts[i] -> {
maxJavaVersion = presetJavaVersion
break
}
inputGradleVersionInts[i] < presetGradleVersionInts[i] -> {
break
}
i == presetGradleVersionInts.lastIndex -> {
maxJavaVersion = presetJavaVersion
}
}
}
}
return maxJavaVersion
}
} }
object Utils { object Utils {

View File

@@ -6,26 +6,40 @@
# v6.6.3 # v6.6.3
###### 2025/05/02 ###### 2025/05/13
* `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据
* `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态
* `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件
* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_
* `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题
* `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题
* `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题
* `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题
* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题
* `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题
* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题
* `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_ * `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_
* `修复` 使用 JavaAdapter 时导致 ClassLoader 调用栈溢出的问题 _[`issue #376`](http://issues.autojs6.com/376)_
* `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_ * `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_
* `修复` README.md 中部分语言日期格式不正确的问题 * `修复` README.md 中部分语言日期格式不正确的问题
* `优化` 关于应用与开发者页面增加水平布局适配 * `优化` 主题色扩充适配范围并支持更多控件类型
* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性
* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配
* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项
* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏
* `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_ * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_
* `优化` 已忽略更新记录及客户端模式连接地址记录支持清空操作
* `优化` 版本更新信息支持多语言显示 (与当前显示语言同步) * `优化` 版本更新信息支持多语言显示 (与当前显示语言同步)
* `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性 * `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性
* `优化` Gradle 构建脚本提升版本自适应能力 _[`discussion #369`](http://discussions.autojs6.com/369)_
* `依赖` 本地化 Material Dialogs 版本 0.9.6.0
* `依赖` 本地化 Material Date Time Picker 版本 4.2.3
* `依赖` 附加 Jsoup 版本 1.19.1 * `依赖` 附加 Jsoup 版本 1.19.1
* `依赖` 附加 Material Progressbar 版本 1.4.2
* `依赖` 附加 Flexmark Java HTML to Markdown 版本 0.64.8 * `依赖` 附加 Flexmark Java HTML to Markdown 版本 0.64.8
* `依赖` 升级 Gradle 版本 8.14-rc-1 -> 8.14-rc-2 * `依赖` 升级 Gradle 版本 8.14-rc-1 -> 8.14
* `依赖` 升级 Androidx Room 版本 2.7.0 -> 2.7.1
# v6.6.2 # v6.6.2

View File

@@ -6,26 +6,40 @@
# v6.6.3 # v6.6.3
###### 2025/05/02 ###### 2025/05/13
* `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据
* `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态
* `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件
* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_
* `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题
* `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题
* `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题
* `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题
* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题
* `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题
* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题
* `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_ * `修复` dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_
* `修复` 使用 JavaAdapter 时导致 ClassLoader 调用栈溢出的问题 _[`issue #376`](http://issues.autojs6.com/376)_
* `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_ * `修复` console.setContentTextColor 方法导致日志字体颜色丢失默认值的问题 _[`issue #346`](http://issues.autojs6.com/346)_
* `修复` README.md 中部分语言日期格式不正确的问题 * `修复` README.md 中部分语言日期格式不正确的问题
* `优化` 关于应用与开发者页面增加水平布局适配 * `优化` 主题色扩充适配范围并支持更多控件类型
* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性
* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配
* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项
* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏
* `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_ * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_
* `优化` 已忽略更新记录及客户端模式连接地址记录支持清空操作
* `优化` 版本更新信息支持多语言显示 (与当前显示语言同步) * `优化` 版本更新信息支持多语言显示 (与当前显示语言同步)
* `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性 * `优化` 使用异步加载方式一定程度提升文件管理器列表滑动流畅性
* `优化` Gradle 构建脚本提升版本自适应能力 _[`discussion #369`](http://discussions.autojs6.com/369)_
* `依赖` 本地化 Material Dialogs 版本 0.9.6.0
* `依赖` 本地化 Material Date Time Picker 版本 4.2.3
* `依赖` 附加 Jsoup 版本 1.19.1 * `依赖` 附加 Jsoup 版本 1.19.1
* `依赖` 附加 Material Progressbar 版本 1.4.2
* `依赖` 附加 Flexmark Java HTML to Markdown 版本 0.64.8 * `依赖` 附加 Flexmark Java HTML to Markdown 版本 0.64.8
* `依赖` 升级 Gradle 版本 8.14-rc-1 -> 8.14-rc-2 * `依赖` 升级 Gradle 版本 8.14-rc-1 -> 8.14
* `依赖` 升级 Androidx Room 版本 2.7.0 -> 2.7.1
# v6.6.2 # v6.6.2

View File

@@ -1,6 +1,6 @@
#Fri Apr 18 11:53:53 CST 2025 #Tue May 13 17:11:16 CST 2025
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-rc-2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -386,9 +386,7 @@ public abstract class V1SchemeSigner {
checkEntryNameValid(entryName); checkEntryNameValid(entryName);
byte[] entryDigest = jarEntryDigests.get(entryName); byte[] entryDigest = jarEntryDigests.get(entryName);
Attributes entryAttrs = new Attributes(); Attributes entryAttrs = new Attributes();
String encodedEntryDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O String encodedEntryDigest = base64EncodeCompat(entryDigest);
? Base64.getEncoder().encodeToString(entryDigest)
: com.mcal.apksigner.utils.Base64.encode(entryDigest);
entryAttrs.putValue(entryDigestAttributeName, encodedEntryDigest); entryAttrs.putValue(entryDigestAttributeName, encodedEntryDigest);
ByteArrayOutputStream sectionOut = new ByteArrayOutputStream(); ByteArrayOutputStream sectionOut = new ByteArrayOutputStream();
byte[] sectionBytes; byte[] sectionBytes;
@@ -409,6 +407,18 @@ public abstract class V1SchemeSigner {
return result; return result;
} }
public static String base64EncodeCompat(byte[] entryDigest) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? Base64.getEncoder().encodeToString(entryDigest)
: com.mcal.apksigner.utils.Base64.encode(entryDigest);
}
public static byte[] base64DecodeCompat(String src) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? Base64.getDecoder().decode(src)
: com.mcal.apksigner.utils.Base64.decode(src);
}
private static void checkEntryNameValid(String name) throws ApkFormatException { private static void checkEntryNameValid(String name) throws ApkFormatException {
// JAR signing spec says CR, LF, and NUL are not permitted in entry names // JAR signing spec says CR, LF, and NUL are not permitted in entry names
// CR or LF in entry names will result in malformed MANIFEST.MF and .SF files because there // CR or LF in entry names will result in malformed MANIFEST.MF and .SF files because there
@@ -460,9 +470,7 @@ public abstract class V1SchemeSigner {
// Add main attribute containing the digest of MANIFEST.MF. // Add main attribute containing the digest of MANIFEST.MF.
MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm); MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm);
String encodedManifestDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O String encodedManifestDigest = base64EncodeCompat(md.digest(manifest.contents));
? Base64.getEncoder().encodeToString(md.digest(manifest.contents))
: com.mcal.apksigner.utils.Base64.encode(md.digest(manifest.contents));
mainAttrs.putValue(getManifestDigestAttributeName(manifestDigestAlgorithm), encodedManifestDigest); mainAttrs.putValue(getManifestDigestAttributeName(manifestDigestAlgorithm), encodedManifestDigest);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
try { try {
@@ -477,9 +485,7 @@ public abstract class V1SchemeSigner {
byte[] sectionContents = manifestSection.getValue(); byte[] sectionContents = manifestSection.getValue();
byte[] sectionDigest = md.digest(sectionContents); byte[] sectionDigest = md.digest(sectionContents);
Attributes attrs = new Attributes(); Attributes attrs = new Attributes();
String encodedSectionDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O String encodedSectionDigest = base64EncodeCompat(sectionDigest);
? Base64.getEncoder().encodeToString(sectionDigest)
: com.mcal.apksigner.utils.Base64.encode(sectionDigest);
attrs.putValue(entryDigestAttributeName, encodedSectionDigest); attrs.putValue(entryDigestAttributeName, encodedSectionDigest);
try { try {

View File

@@ -17,6 +17,8 @@
package com.android.apksig.internal.apk.v1; package com.android.apksig.internal.apk.v1;
import static com.android.apksig.Constants.MAX_APK_SIGNERS; import static com.android.apksig.Constants.MAX_APK_SIGNERS;
import static com.android.apksig.internal.apk.v1.V1SchemeSigner.base64DecodeCompat;
import static com.android.apksig.internal.apk.v1.V1SchemeSigner.base64EncodeCompat;
import static com.android.apksig.internal.oid.OidConstants.getSigAlgSupportedApiLevels; import static com.android.apksig.internal.oid.OidConstants.getSigAlgSupportedApiLevels;
import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaDigestAlgorithm; import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaDigestAlgorithm;
import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaSignatureAlgorithm; import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaSignatureAlgorithm;
@@ -69,8 +71,6 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -971,8 +971,8 @@ public abstract class V1SchemeVerifier {
V1SchemeConstants.MANIFEST_ENTRY_NAME, V1SchemeConstants.MANIFEST_ENTRY_NAME,
jcaDigestAlgorithm, jcaDigestAlgorithm,
mSignatureFileEntry.getName(), mSignatureFileEntry.getName(),
Base64.getEncoder().encodeToString(actual), base64EncodeCompat(actual),
Base64.getEncoder().encodeToString(expected)); base64EncodeCompat(expected));
verified = false; verified = false;
} }
} }
@@ -1013,8 +1013,8 @@ public abstract class V1SchemeVerifier {
Issue.JAR_SIG_MANIFEST_MAIN_SECTION_DIGEST_DID_NOT_VERIFY, Issue.JAR_SIG_MANIFEST_MAIN_SECTION_DIGEST_DID_NOT_VERIFY,
jcaDigestAlgorithm, jcaDigestAlgorithm,
mSignatureFileEntry.getName(), mSignatureFileEntry.getName(),
Base64.getEncoder().encodeToString(actual), base64EncodeCompat(actual),
Base64.getEncoder().encodeToString(expected)); base64EncodeCompat(expected));
} }
} }
} }
@@ -1066,8 +1066,8 @@ public abstract class V1SchemeVerifier {
entryName, entryName,
jcaDigestAlgorithm, jcaDigestAlgorithm,
mSignatureFileEntry.getName(), mSignatureFileEntry.getName(),
Base64.getEncoder().encodeToString(actual), base64EncodeCompat(actual),
Base64.getEncoder().encodeToString(expected)); base64EncodeCompat(expected));
} }
} }
} }
@@ -1142,7 +1142,6 @@ public abstract class V1SchemeVerifier {
String digestAttrSuffix, String digestAttrSuffix,
int minSdkVersion, int minSdkVersion,
int maxSdkVersion) { int maxSdkVersion) {
Decoder base64Decoder = Base64.getDecoder();
List<NamedDigest> result = new ArrayList<>(1); List<NamedDigest> result = new ArrayList<>(1);
if (minSdkVersion < AndroidSdkVersion.JELLY_BEAN_MR2) { if (minSdkVersion < AndroidSdkVersion.JELLY_BEAN_MR2) {
// Prior to JB MR2, Android platform's logic for picking a digest algorithm to verify is // Prior to JB MR2, Android platform's logic for picking a digest algorithm to verify is
@@ -1171,7 +1170,7 @@ public abstract class V1SchemeVerifier {
continue; continue;
} }
// Supported digest algorithm // Supported digest algorithm
result.add(new NamedDigest(alg, base64Decoder.decode(digestBase64))); result.add(new NamedDigest(alg, base64DecodeCompat(digestBase64)));
break; break;
} }
// No supported digests found -- this will fail to verify on pre-JB MR2 Androids. // No supported digests found -- this will fail to verify on pre-JB MR2 Androids.
@@ -1190,7 +1189,7 @@ public abstract class V1SchemeVerifier {
// Attribute not found // Attribute not found
continue; continue;
} }
byte[] digest = base64Decoder.decode(digestBase64); byte[] digest = base64DecodeCompat(digestBase64);
byte[] digestInResult = getDigest(result, alg); byte[] digestInResult = getDigest(result, alg);
if ((digestInResult == null) || (!Arrays.equals(digestInResult, digest))) { if ((digestInResult == null) || (!Arrays.equals(digestInResult, digest))) {
result.add(new NamedDigest(alg, digest)); result.add(new NamedDigest(alg, digest));
@@ -1373,8 +1372,8 @@ public abstract class V1SchemeVerifier {
entryName, entryName,
expectedDigest.jcaDigestAlgorithm, expectedDigest.jcaDigestAlgorithm,
V1SchemeConstants.MANIFEST_ENTRY_NAME, V1SchemeConstants.MANIFEST_ENTRY_NAME,
Base64.getEncoder().encodeToString(actualDigest), base64EncodeCompat(actualDigest),
Base64.getEncoder().encodeToString(expectedDigest.digest)); base64EncodeCompat(expectedDigest.digest));
} }
} }
} }

View File

@@ -16,6 +16,8 @@
package com.android.apksig.internal.util; package com.android.apksig.internal.util;
import static com.android.apksig.internal.apk.v1.V1SchemeSigner.base64DecodeCompat;
import com.android.apksig.internal.asn1.Asn1BerParser; import com.android.apksig.internal.asn1.Asn1BerParser;
import com.android.apksig.internal.asn1.Asn1DecodingException; import com.android.apksig.internal.asn1.Asn1DecodingException;
import com.android.apksig.internal.asn1.Asn1DerEncoder; import com.android.apksig.internal.asn1.Asn1DerEncoder;
@@ -30,7 +32,6 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection; import java.util.Collection;
/** /**
@@ -265,7 +266,7 @@ public class X509CertificateUtils {
+ "valid certificate footer"); + "valid certificate footer");
} }
} }
byte[] derEncoding = Base64.getDecoder().decode(pemEncoding.toString()); byte[] derEncoding = base64DecodeCompat(pemEncoding.toString());
// consume any trailing whitespace in the byte buffer // consume any trailing whitespace in the byte buffer
int nextEncodedChar = certificateBuffer.position(); int nextEncodedChar = certificateBuffer.position();
while (certificateBuffer.hasRemaining()) { while (certificateBuffer.hasRemaining()) {

View File

@@ -16,6 +16,8 @@
package com.android.apksigner; package com.android.apksigner;
import android.annotation.SuppressLint;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.Console; import java.io.Console;
import java.io.File; import java.io.File;
@@ -86,7 +88,7 @@ public class PasswordRetriever implements AutoCloseable {
return encoded; return encoded;
} }
private static char[] decodePassword(byte[] pwdBytes, Charset encoding) throws IOException { private static char[] decodePassword(byte[] pwdBytes, Charset encoding) throws IOException {
CharBuffer pwdChars = CharBuffer pwdChars =
encoding.newDecoder() encoding.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE) .onMalformedInput(CodingErrorAction.REPLACE)
@@ -140,6 +142,7 @@ public class PasswordRetriever implements AutoCloseable {
} }
String consoleCharsetName = null; String consoleCharsetName = null;
try { try {
@SuppressLint("SoonBlockedPrivateApi")
Method encodingMethod = Console.class.getDeclaredMethod("encoding"); Method encodingMethod = Console.class.getDeclaredMethod("encoding");
encodingMethod.setAccessible(true); encodingMethod.setAccessible(true);
consoleCharsetName = (String) encodingMethod.invoke(null); consoleCharsetName = (String) encodingMethod.invoke(null);
@@ -314,7 +317,7 @@ public class PasswordRetriever implements AutoCloseable {
if (value == null) { if (value == null) {
throw new IOException( throw new IOException(
"Failed to read " + description + ": environment variable " + value "Failed to read " + description + ": environment variable " + value
+ " not specified"); + " not specified");
} }
return getPasswords(value.toCharArray(), additionalPwdEncodings); return getPasswords(value.toCharArray(), additionalPwdEncodings);
} else { } else {

View File

@@ -1,30 +1,5 @@
@file:Suppress("SpellCheckingInspection") @file:Suppress("SpellCheckingInspection")
// @Hint by SuperMonster003 on May 3, 2023.
// ! To download archives of Android Studio,
// ! visit https://developer.android.com/studio/archive?hl=en.
// ! zh-CN:
// ! 下载 Android Studio 档案,
// ! 可访问 https://developer.android.com/studio/archive?hl=en.
// !
// ! To check the releases for AGP (Android Gradle Plugin),
// ! visit https://developer.android.com/reference/tools/gradle-api.
// ! zh-CN:
// ! 查看 AGP (Android Gradle Plugin) 发行版本,
// ! 可访问 https://developer.android.com/reference/tools/gradle-api.
// !
// ! To check the compatibility and released date of kotlin plugins,
// ! visit https://plugins.jetbrains.com/plugin/6954-kotlin/versions/eap.
// ! zh-CN:
// ! 查看 kotlin 插件的兼容性及其发行版本,
// ! 可访问 https://plugins.jetbrains.com/plugin/6954-kotlin/versions/eap.
// !
// ! To check the releases for KSP (Kotlin Symbol Processing) plugin,
// ! visit https://github.com/google/ksp/releases.
// ! zh-CN:
// ! 查看 KSP (Kotlin Symbol Processing) 插件的发行版本,
// ! 可访问 https://github.com/google/ksp/releases.
private val modules = listOf( private val modules = listOf(
"jieba-analysis", "jieba-analysis",
"apk-signer", "apk-signer",
@@ -67,9 +42,103 @@ modules.forEach {
pluginManagement { pluginManagement {
// @Hint by SuperMonster003 on May 13, 2025.
// ! Change the null value to specify a version (instead of auto-selection), e.g. 23 or "8.3.0-beta02".
// ! zh-CN: 如需指定版本 (而非自动选择版本), 可修改相应的 null 值, 如 23 或 "8.3.0-beta02".
// !
// ! Gradle JVM
val overriddenJavaVersion: Int? = null
// ! classpath("com.android.tools.build:gradle")
val overriddenAgpVersion: String? = null
// ! classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
val overriddenKotlinVersion: String? = null
// ! plugin("com.google.devtools.ksp")
val overriddenKspVersion: String? = null
// @Signature Pair<Gradle Version, Embedded Compatible Kotlin Version>
// @Reference gradle-<version>-src.zip\gradle\dependency-management\kotlin-version.properties
// @Reference https://docs.gradle.org/current/userguide/compatibility.html#kotlin
// @Updated by SuperMonster003 on May 12, 2025.
val embeddedKotlin: List<Pair<String, String>> = listOf(
/* Unofficial. */
"9.0" to "2.1.20",
"8.14" to "2.1.10",
"8.13" to "2.1.10",
/* Official. */
"8.12" to "2.0.21",
"8.11" to "2.0.20",
"8.10" to "1.9.24",
"8.9" to "1.9.23",
"8.7" to "1.9.22",
"8.5" to "1.9.20",
"8.4" to "1.9.10",
"8.3" to "1.9.0",
"8.2" to "1.8.20",
"8.0" to "1.8.10",
)
// @Signature Pair<Supported Java Version, Min Required Gradle Version>
// @Reference https://docs.gradle.org/current/userguide/compatibility.html#java_runtime
// @Updated by SuperMonster003 on May 12, 2025.
val javaGradleCompatibility = listOf(
/* Unofficial. */
25 to "9.0",
/* Official. */
24 to "8.14",
23 to "8.10",
22 to "8.8",
21 to "8.5",
20 to "8.3",
19 to "7.6",
18 to "7.5",
17 to "7.3",
)
// @Signature Pair<Android Gradle Plugin Version, Min Required Gradle Version>
// @Reference https://developer.android.com/build/releases/gradle-plugin#updating-gradle
// @Updated by SuperMonster003 on May 13, 2025.
val agpGradleCompatibility: List<Pair<String, String>> = listOf(
"8.9" to "8.11.1",
"8.8" to "8.10.2",
"8.7" to "8.9",
"8.6" to "8.7",
"8.5" to "8.7",
"8.4" to "8.6",
"8.3" to "8.4",
"8.2" to "8.2",
"8.1" to "8.0",
"8.0" to "8.0",
"7.4" to "7.5",
"7.3" to "7.4",
)
// @Reference https://developer.android.com/reference/tools/gradle-api
// @Updated by SuperMonster003 on May 13, 2025.
val agpReleases: List<String> = listOf(
"8.11.0-alpha10",
"8.10.0",
"8.9.2",
"8.8.2",
"8.7.3",
"8.6.1",
"8.5.2",
"8.4.2",
"8.3.2",
"8.2.2",
"8.1.4",
"8.0.2",
"7.4.2",
)
val consts = object { val consts = object {
val IDENTIFIER_FALLBACK = "fallback"
val IDENTIFIER_UNKNOWN = "unknown"
val DEFAULT_VERSION = "0" val DEFAULT_VERSION = "0"
} }
@@ -134,41 +203,36 @@ pluginManagement {
/* Print concerned info by `System.getProperties()`. */ /* Print concerned info by `System.getProperties()`. */
val isShowConcernedSystemProperties = true val isShowConcernedSystemProperties = true
/* https://docs.gradle.org/current/userguide/compatibility.html . */
val isJavaVersionCoercedByGradleVersion = true
val isCleanupPaddleOcr = false val isCleanupPaddleOcr = false
val isCleanupRapidOcr = false val isCleanupRapidOcr = false
val fallbackGradleVersion = "8.0.2" val fallbackAgpVersion = "7.4.2"
val fallbackKotlinVersion = "1.9.22" val fallbackKotlinVersion = "1.7.10"
val recommendedMinGradleVersion = "8.5.2"
val recommendedMinKotlinVersion = "1.9.24"
@Suppress("unused") @Suppress("unused")
val platforms = object { val platforms = object {
val androidStudio = object : Platform( val androidStudio = object : Platform(
name = "AndroidStudio", vendor = "Google", name = "AndroidStudio", vendor = "Google",
androidVersionMap = mapOf( // @Reference https://developer.android.com/studio/releases#android_gradle_plugin_and_android_studio_compatibility
"2025.1" to "8.10.0-rc02", /* Apr 11, 2025. */ // @Updated by SuperMonster003 on May 13, 2025.
"2024.3" to "8.9.1", /* Apr 11, 2025. */ agpVersionMap = mapOf(
"2024.2" to "8.8.0", /* Jan 13, 2025. */ "2025.1" to "8.10.0", /* May 13, 2025. */
"2024.1" to "8.6.0", /* Aug 30, 2024. */ "2024.3" to "8.9.2", /* Apr 11, 2025. */
"2023.3" to "8.5.0-alpha02", /* Mar 28, 2024. */ "2024.2" to "8.7.3", /* Jan 13, 2025. */
"2023.2" to "8.3.0-rc02", /* Feb 14, 2024. */ "2024.1" to "8.5.2", /* Aug 30, 2024. */
"2023.3" to "8.4.2", /* Mar 28, 2024. */
"2023.2" to "8.3.2", /* Feb 14, 2024. */
"2023.1" to "8.2.2", /* Feb 6, 2024. */ "2023.1" to "8.2.2", /* Feb 6, 2024. */
"2022.3" to "8.1.4", /* Mar 31, 2024. */ "2022.3" to "8.1.4", /* Mar 31, 2024. */
"2022.2" to "8.0.2", /* May 26, 2023. */ "2022.2" to "8.0.2", /* May 26, 2023. */
"2022.1" to "7.4.2", /* Mar 25, 2023. */ "2022.1" to "7.4.2", /* Mar 25, 2023. */
consts.IDENTIFIER_FALLBACK to fallbackGradleVersion,
), ),
// @Updated by SuperMonster003 on May 13, 2025.
kotlinVersionMap = mapOf( kotlinVersionMap = mapOf(
"2025.1" to "2.1.20", /* Apr 11, 2025. */
"2024.3" to "2.1.20", /* Apr 11, 2024. */ "2024.3" to "2.1.20", /* Apr 11, 2024. */
"2024.2" to "2.1.0", /* Nov 29, 2024. */ "2024.2" to "2.1.0", /* Nov 29, 2024. */
"2024.1" to "2.0.0", /* Aug 13, 2024. */ "2024.1" to "2.0.0", /* Aug 13, 2024. */
consts.IDENTIFIER_FALLBACK to fallbackKotlinVersion,
), ),
codenameVersionMap = mapOf( codenameVersionMap = mapOf(
"2025.1" to "N", /* Apr 11, 2025. */ "2025.1" to "N", /* Apr 11, 2025. */
@@ -196,9 +260,11 @@ pluginManagement {
"D" to "Dolphin", /* Born on Jan 31, 2022. */ "D" to "Dolphin", /* Born on Jan 31, 2022. */
"C" to "Chipmunk", /* Born on Oct 13, 2021. */ "C" to "Chipmunk", /* Born on Oct 13, 2021. */
"B" to "Bumblebee", /* Born on May 18, 2021. */ "B" to "Bumblebee", /* Born on May 18, 2021. */
"A" to "Arctic Fox", /* Born on Jan 26, 2021. */ "A" to "Arctic Fox",
/* Born on Jan 26, 2021. */
/* Codenames below were predicted on Oct 18, 2023. */ // @Hint by SuperMonster003 on Oct 18, 2023.
// ! The codenames below were predicted but not official.
"O" to "Ostrich", "P" to "Penguin", "Q" to "Quail", "O" to "Ostrich", "P" to "Penguin", "Q" to "Quail",
"R" to "Rhino", "S" to "Snail", "T" to "Tiger", "R" to "Rhino", "S" to "Snail", "T" to "Tiger",
@@ -220,7 +286,8 @@ pluginManagement {
val intelliJIdea = object : Platform( val intelliJIdea = object : Platform(
name = "IntelliJIdea", vendor = "Jetbrains", name = "IntelliJIdea", vendor = "Jetbrains",
androidVersionMap = mapOf( // @Updated by SuperMonster003 on Apr 23, 2025.
agpVersionMap = mapOf(
"2025.1" to "8.9.2", /* Apr 23, 2025. */ "2025.1" to "8.9.2", /* Apr 23, 2025. */
"2024.3.1" to "8.7.3", /* Dec 10, 2024. */ "2024.3.1" to "8.7.3", /* Dec 10, 2024. */
"2024.3" to "8.7.0-rc01", /* Nov 15, 2024. */ "2024.3" to "8.7.0-rc01", /* Nov 15, 2024. */
@@ -229,8 +296,8 @@ pluginManagement {
"2023.3" to "8.2.2", /* Jan 19, 2024. */ "2023.3" to "8.2.2", /* Jan 19, 2024. */
"2023.1" to "7.4.2", /* May 26, 2023. */ "2023.1" to "7.4.2", /* May 26, 2023. */
"2022.3" to "7.4.0-beta02", /* Mar 25, 2023. */ "2022.3" to "7.4.0-beta02", /* Mar 25, 2023. */
consts.IDENTIFIER_FALLBACK to fallbackGradleVersion,
), ),
// @Updated by SuperMonster003 on Apr 23, 2025.
kotlinVersionMap = mapOf( kotlinVersionMap = mapOf(
"2025.1" to "2.1.20", /* Apr 12, 2025. */ "2025.1" to "2.1.20", /* Apr 12, 2025. */
"2024.3.4" to "2.1.10", /* Feb 28, 2025. */ "2024.3.4" to "2.1.10", /* Feb 28, 2025. */
@@ -238,7 +305,6 @@ pluginManagement {
"2024.2" to "2.0.21-RC", /* Sep 27, 2024. */ "2024.2" to "2.0.21-RC", /* Sep 27, 2024. */
"2024.1" to "1.9.24", /* Dec 3, 2024. */ "2024.1" to "1.9.24", /* Dec 3, 2024. */
"2023.3" to "1.9.23", /* Mar 29, 2024. */ "2023.3" to "1.9.23", /* Mar 29, 2024. */
consts.IDENTIFIER_FALLBACK to fallbackKotlinVersion,
), ),
) { ) {
override val weight = 10 override val weight = 10
@@ -248,15 +314,13 @@ pluginManagement {
val temurin = object : Platform( val temurin = object : Platform(
name = "Temurin", vendor = "temurin", /* More common as "Eclipse Adoptium". */ name = "Temurin", vendor = "temurin", /* More common as "Eclipse Adoptium". */
androidVersionMap = mapOf( agpVersionMap = mapOf(
"21.0.6+7" to "8.7.3", /* Apr 16, 2025. */ "21.0.6+7" to "8.7.3", /* Apr 16, 2025. */
"20.0.2+9" to "8.2.2", /* Dec 2, 2024. */ "20.0.2+9" to "8.2.2", /* Dec 2, 2024. */
consts.IDENTIFIER_FALLBACK to recommendedMinGradleVersion,
), ),
kotlinVersionMap = mapOf( kotlinVersionMap = mapOf(
"21.0.6+7" to "2.1.10", /* Apr 16, 2025. */ "21.0.6+7" to "2.1.10", /* Apr 16, 2025. */
"20.0.2+9" to "1.9.24", /* Dec 2, 2024. */ "20.0.2+9" to "1.9.24", /* Dec 2, 2024. */
consts.IDENTIFIER_FALLBACK to recommendedMinKotlinVersion,
), ),
) { ) {
override val weight = 5 override val weight = 5
@@ -264,13 +328,7 @@ pluginManagement {
} }
val unknown = object : Platform( val unknown = object : Platform(
name = "Unknown", vendor = consts.IDENTIFIER_UNKNOWN, name = "Unknown", vendor = "unknown",
androidVersionMap = mapOf(
consts.IDENTIFIER_FALLBACK to recommendedMinGradleVersion,
),
kotlinVersionMap = mapOf(
consts.IDENTIFIER_FALLBACK to recommendedMinKotlinVersion,
),
) { ) {
fun declare() = systemProperties.platform?.let { fun declare() = systemProperties.platform?.let {
println("Unexpected platform: $it") println("Unexpected platform: $it")
@@ -310,17 +368,20 @@ pluginManagement {
} }
/* Change "version" argument to specify a version, e.g. "8.3.0-beta02". */
val libs = listOf( val libs = listOf(
Classpath(id = "com.android.tools.build:gradle", version = "auto:android"), Classpath(id = "com.android.tools.build:gradle", version = overriddenAgpVersion ?: "auto:agp"),
Classpath(id = "org.jetbrains.kotlin:kotlin-gradle-plugin", version = "auto:kotlin"), Classpath(id = "org.jetbrains.kotlin:kotlin-gradle-plugin", version = overriddenKotlinVersion ?: "auto:kotlin"),
Plugin(id = "com.google.devtools.ksp", version = "auto:ksp"), Plugin(id = "com.google.devtools.ksp", version = overriddenKspVersion ?: "auto:ksp"),
) )
// @Reference https://github.com/google/ksp/releases
// @Updated by SuperMonster003 on May 13, 2025.
val kspVersionMap = mapOf( val kspVersionMap = mapOf(
"2.2.0-Beta2" to "2.0.1", /* May 2, 2025. */
"2.2.0-Beta1" to "2.0.0", /* Apr 17, 2025. */ "2.2.0-Beta1" to "2.0.0", /* Apr 17, 2025. */
"2.1.21-RC2" to "2.0.1", /* May 2, 2025. */
"2.1.21-RC" to "2.0.0", /* Apr 18, 2025. */ "2.1.21-RC" to "2.0.0", /* Apr 18, 2025. */
"2.1.20" to "2.0.0", /* Apr 9, 2025. */ "2.1.20" to "2.0.1", /* May 1, 2025. */
"2.1.20-RC3" to "1.0.31", /* Mar 15, 2025. */ "2.1.20-RC3" to "1.0.31", /* Mar 15, 2025. */
"2.1.20-RC2" to "1.0.31", /* Mar 7, 2025. */ "2.1.20-RC2" to "1.0.31", /* Mar 7, 2025. */
"2.1.20-RC" to "1.0.31", /* Feb 28, 2025. */ "2.1.20-RC" to "1.0.31", /* Feb 28, 2025. */
@@ -369,14 +430,13 @@ pluginManagement {
"1.8.20-RC2" to "1.0.9", /* Aug 16, 2023. */ "1.8.20-RC2" to "1.0.9", /* Aug 16, 2023. */
"1.8.0" to "1.0.9", /* Aug 16, 2023. */ "1.8.0" to "1.0.9", /* Aug 16, 2023. */
"1.8.0-RC2" to "1.0.8", /* Aug 16, 2023. */ "1.8.0-RC2" to "1.0.8", /* Aug 16, 2023. */
consts.IDENTIFIER_FALLBACK to "1.9.24-1.0.20", /* Dec 3, 2024. */
) )
abstract inner class Platform( abstract inner class Platform(
var name: String, var name: String,
val vendor: String, val vendor: String,
val androidVersionMap: Map<String, String>, val agpVersionMap: Map<String, String> = emptyMap(),
val kotlinVersionMap: Map<String, String>, val kotlinVersionMap: Map<String, String> = emptyMap(),
val codenameVersionMap: Map<String, String>? = null, val codenameVersionMap: Map<String, String>? = null,
val codenameMap: Map<String, String>? = null, val codenameMap: Map<String, String>? = null,
) { ) {
@@ -438,16 +498,21 @@ pluginManagement {
// ! zh-CN: // ! zh-CN:
// ! Fallback (回退) 是一种临时或替代的解决方法, 用于应对功能不可用的特定情况. // ! Fallback (回退) 是一种临时或替代的解决方法, 用于应对功能不可用的特定情况.
// ! Compatibility (兼容) 是一种更广泛的设计原则, 确保新版本能兼容并继续支持旧版本的操作和数据. // ! Compatibility (兼容) 是一种更广泛的设计原则, 确保新版本能兼容并继续支持旧版本的操作和数据.
val fallback = consts.IDENTIFIER_FALLBACK val fallback = "fallback"
val compatible = "compatible"
val upgraded = "upgraded"
val downgraded = "downgraded"
val nearestLowerMatched = "nearest-lower-matched"
val specified = "specified" val specified = "specified"
val auto = "auto" val auto = "auto"
val fallbackSuffix = " [$fallback]" val fallbackSuffix = " [$fallback]"
val compatibleSuffix = " [$compatible]" val upgradedSuffix = " [$upgraded]"
val specifiedSuffix = " [$specified]" val downgradedSuffix = " [$downgraded]"
val nearestLowerMatchedSuffix = " [$nearestLowerMatched]"
val autoSpecifiedSuffix = " [$auto-$specified]" val autoSpecifiedSuffix = " [$auto-$specified]"
val userSpecifiedSuffix = " [user-$specified]"
} }
@@ -474,7 +539,69 @@ pluginManagement {
val notations = object { val notations = object {
private val kotlinVersionMap = platform.kotlinVersionMap private val versions = object {
val agp = object : Version(platform.agpVersionMap, platform.version, config.fallbackAgpVersion) {
override fun refinedBestMatchingValue(bestMatchingValue: String?): String? {
val currentGradleVersion = gradle.gradleVersion.toGradleVersion()
val sorted = agpGradleCompatibility.sortedByDescending { it.second.toGradleVersion() }
var maxSupporedAgpVersionPrefix: String? = null
for (pair in sorted) {
maxSupporedAgpVersionPrefix = pair.first
if (currentGradleVersion >= pair.second.toGradleVersion()) {
break
}
}
val maxSupporedAgpVersion = maxSupporedAgpVersionPrefix?.let { getAgpReleasedVersion(it) }
return when {
maxSupporedAgpVersion == null -> bestMatchingValue
bestMatchingValue == null -> {
bestMatchingOperationHintSuffix = identifier.autoSpecifiedSuffix
maxSupporedAgpVersion
}
compareVersionStrings(bestMatchingValue, maxSupporedAgpVersion) > 0 -> {
bestMatchingOperationHintSuffix = identifier.downgradedSuffix
maxSupporedAgpVersion
}
else -> bestMatchingValue
}
}
private fun getAgpReleasedVersion(referenceAgpVersion: String): String? {
return agpReleases.find { it.startsWith(referenceAgpVersion) && !it.contains("-") }
}
}
val kotlin = object : Version(platform.kotlinVersionMap, platform.version, config.fallbackKotlinVersion) {
override fun refinedBestMatchingValue(bestMatchingValue: String?): String? {
val currentGradleVersion = gradle.gradleVersion.toGradleVersion()
val embeddedMin = embeddedKotlin
.filter { (gradleMin, _) -> currentGradleVersion >= gradleMin.toGradleVersion() }
.maxByOrNull { it.first.toGradleVersion() }
?.second
return when {
embeddedMin == null -> bestMatchingValue
bestMatchingValue == null -> {
bestMatchingOperationHintSuffix = identifier.autoSpecifiedSuffix
embeddedMin
}
bestMatchingValue.toGradleVersion() < embeddedMin.toGradleVersion() -> {
bestMatchingOperationHintSuffix = identifier.upgradedSuffix
embeddedMin
}
bestMatchingValue.toGradleVersion() > embeddedMin.toGradleVersion() -> {
bestMatchingOperationHintSuffix = identifier.downgradedSuffix
embeddedMin
}
else -> bestMatchingValue
}
}
}
}
private val pluginVersionAutomatorMap: Map<String, (Map<String, String>) -> Map<String, String?>> = mapOf( private val pluginVersionAutomatorMap: Map<String, (Map<String, String>) -> Map<String, String?>> = mapOf(
"ksp" to { versionMap: Map<String, String> -> "ksp" to { versionMap: Map<String, String> ->
@@ -484,94 +611,90 @@ pluginManagement {
.find { it.id.contains("kotlin-gradle-plugin", true) } .find { it.id.contains("kotlin-gradle-plugin", true) }
?.takeIf { !it.version.startsWith("${identifier.auto}:") } ?.takeIf { !it.version.startsWith("${identifier.auto}:") }
?.version?.let { kt -> ?.version?.let { kt ->
suffix += identifier.autoSpecifiedSuffix
versionMap[kt]?.let { kt } versionMap[kt]?.let { kt }
} }
?: Version(kotlinVersionMap, platform.version).bestMatchingValue ?: versions.kotlin.bestMatchingValue?.also {
?: kotlinVersionMap[identifier.fallback]?.let { kt -> suffix += identifier.autoSpecifiedSuffix
}
?: versions.kotlin.fallbackVersion?.let { kt ->
suffix += identifier.fallbackSuffix suffix += identifier.fallbackSuffix
versionMap[kt]?.let { kt } versionMap[kt]?.let { kt }
} }
val kspVersion = kotlinVersion?.let { kt -> val kspVersion = kotlinVersion?.let { kt ->
val ver = Version(config.kspVersionMap, kt) val ver = Version(config.kspVersionMap, kt)
ver.bestMatchingKey?.let { key -> val key = ver.bestMatchingKey ?: return@let null
if (ver.isBestMatchingOperated) suffix += identifier.compatibleSuffix val value = ver.bestMatchingValue ?: return@let null
"$key-${ver.bestMatchingValue}" ver.bestMatchingOperationHintSuffix?.let { suffix += it }
} "$key-$value"
} }
mapOf("version" to kspVersion, "suffix" to suffix) mapOf("version" to kspVersion, "suffix" to suffix)
}, },
) )
val classpath = config.libs.filterIsInstance<Classpath>().map { val classpath = config.libs.filterIsInstance<Classpath>().map { lib ->
var suffix = "" var suffix = ""
val version: String = when { val version: String = when {
it.version.startsWith("${identifier.auto}:") -> { lib.version.startsWith("${identifier.auto}:") -> {
val mapType = it.version.substring("${identifier.auto}:".length) val mapType = lib.version.substring("${identifier.auto}:".length)
val map = when (mapType) { val ver = when (mapType) {
"android" -> platform.androidVersionMap "agp" -> versions.agp
"kotlin" -> platform.kotlinVersionMap "kotlin" -> versions.kotlin
else -> throw Exception("Unknown version ${it.version} for classpath ${it.id}") else -> throw Exception("Unknown version ${lib.version} for classpath ${lib.id}")
} }
val ver = Version(map, platform.version) ver.bestMatchingValue?.also {
ver.bestMatchingKey?.let { ver.bestMatchingOperationHintSuffix?.let { s -> suffix += s }
if (ver.isBestMatchingOperated) suffix += identifier.compatibleSuffix } ?: ver.fallbackVersion?.also {
ver.bestMatchingValue
} ?: map[identifier.fallback]?.also {
suffix += identifier.fallbackSuffix suffix += identifier.fallbackSuffix
} ?: consts.DEFAULT_VERSION } ?: consts.DEFAULT_VERSION
} }
else -> it.version.also { else -> lib.version.also {
suffix += identifier.specifiedSuffix suffix += identifier.userSpecifiedSuffix
} }
} }
if (config.isJavaVersionCoercedByGradleVersion && it.id == "com.android.tools.build:gradle") { if (lib.id == "com.android.tools.build:gradle") {
gradle.extra.set("gradleVersionToCoerceJavaVersion", version) gradle.extra.set("javaVersionCoercedByGradle", getMaxSupportedJavaVersion(version))
gradle.extra.set("javaVersionOverriddenByUser", overriddenJavaVersion)
} }
"${it.id}:$version".also { notation -> "${lib.id}:$version".also { notation ->
console.versionInfo += "Classpath: \"$notation\"$suffix" console.versionInfo += "Classpath: \"$notation\"$suffix"
} }
} }
val plugins = config.libs.filterIsInstance<Plugin>().map { val plugins = config.libs.filterIsInstance<Plugin>().map { lib ->
var suffix = "" var suffix = ""
val version: String = when { val version: String = when {
it.version.startsWith("${identifier.auto}:") -> { lib.version.startsWith("${identifier.auto}:") -> {
val automator = pluginVersionAutomatorMap[it.version.substring("${identifier.auto}:".length)]!! val automator = pluginVersionAutomatorMap[lib.version.substring("${identifier.auto}:".length)]!!
val result = automator.invoke(config.kspVersionMap) val result = automator.invoke(config.kspVersionMap)
result["suffix"]?.let { s -> suffix += s } result["suffix"]?.let { s -> suffix += s }
result["version"] ?: throw Exception("Unknown version for plugin ${it.id}") result["version"] ?: throw Exception("Unknown version for plugin ${lib.id}")
} }
else -> { else -> {
suffix += identifier.specifiedSuffix suffix += identifier.userSpecifiedSuffix
it.version lib.version
} }
} }
console.versionInfo += "Plugin: \"${it.id}:$version\"$suffix" console.versionInfo += "Plugin: \"${lib.id}:$version\"$suffix"
mapOf("id" to it.id, "version" to version, "isApply" to it.isApply) mapOf("id" to lib.id, "version" to version, "isApply" to lib.isApply)
} }
private inner class Version(private val map: Map<String, String>, platformVersion: String) { private open inner class Version(val map: Map<String, String>, platformVersion: String, val fallbackVersion: String? = null) {
val bestMatchingKey: String? val bestMatchingKey: String? = findBestMatchingMapKey(platformVersion)
val bestMatchingValue: String?
val isBestMatchingOperated: Boolean
init { var bestMatchingOperationHintSuffix: String? = identifier.nearestLowerMatchedSuffix.takeIf {
bestMatchingKey = findBestMatchingMapKey(platformVersion) bestMatchingKey != null && bestMatchingKey != platformVersion
bestMatchingValue = bestMatchingKey?.let { map[it] }
isBestMatchingOperated = bestMatchingKey != null && bestMatchingKey != platformVersion
} }
private fun findBestMatchingMapKey(platformVersion: String): String? { val bestMatchingValue: String? = refinedBestMatchingValue(bestMatchingKey?.let { map[it] })
open fun refinedBestMatchingValue(bestMatchingValue: String?) = bestMatchingValue
fun findBestMatchingMapKey(platformVersion: String): String? {
val (platformVersionNumbers, platformVersionSuffix) = toVersionParts(platformVersion) val (platformVersionNumbers, platformVersionSuffix) = toVersionParts(platformVersion)
val sortedVersions = map.keys.filter { it != identifier.fallback }.sortedWith { v1, v2 -> val sortedVersions = map.keys.filter { it != identifier.fallback }.sortedWith(::compareVersionStrings).reversed()
val (ver1Numbers, ver1Suffix) = toVersionParts(v1)
val (ver2Numbers, ver2Suffix) = toVersionParts(v2)
compareVersionParts(ver2Numbers, ver1Numbers).takeIf { it != 0 } ?: compareSuffix(ver2Suffix, ver1Suffix)
}
for (version in sortedVersions) { for (version in sortedVersions) {
val (versionNumbers, versionSuffix) = toVersionParts(version) val (versionNumbers, versionSuffix) = toVersionParts(version)
val versionComparisonScore = compareVersionParts(versionNumbers, platformVersionNumbers) val versionComparisonScore = compareVersionParts(versionNumbers, platformVersionNumbers)
@@ -585,6 +708,14 @@ pluginManagement {
return null return null
} }
fun compareVersionStrings(v1: String, v2: String): Int {
val (ver1Numbers, ver1Suffix) = toVersionParts(v1)
val (ver2Numbers, ver2Suffix) = toVersionParts(v2)
return compareVersionParts(ver1Numbers, ver2Numbers)
.takeIf { it != 0 }
?: compareSuffix(ver1Suffix, ver2Suffix)
}
private fun compareVersionParts(parts1: List<Int>, parts2: List<Int>): Int { private fun compareVersionParts(parts1: List<Int>, parts2: List<Int>): Int {
for (i in 0 until maxOf(parts1.size, parts2.size)) { for (i in 0 until maxOf(parts1.size, parts2.size)) {
val part1 = parts1.getOrElse(i) { 0 } val part1 = parts1.getOrElse(i) { 0 }
@@ -620,6 +751,42 @@ pluginManagement {
} }
private fun String.toGradleVersion() = GradleVersion.version(this)
private fun getMaxSupportedJavaVersion(gradleVersion: String): Int {
fun parseVersion(version: String) = version.split(Regex("[.-]")).map { it.toIntOrNull() ?: 0 }
val inputGradleVersionInts = parseVersion(gradleVersion)
val sortedJavaGradleCompatibility = javaGradleCompatibility.sortedBy { it.first }
var maxJavaVersion: Int = sortedJavaGradleCompatibility.first().first
for ((presetJavaVersion, presetGradleVersion) in sortedJavaGradleCompatibility) {
val presetGradleVersionInts: List<Int> = parseVersion(presetGradleVersion)
for (i in presetGradleVersionInts.indices) {
when {
i > inputGradleVersionInts.lastIndex -> {
break
}
inputGradleVersionInts[i] > presetGradleVersionInts[i] -> {
maxJavaVersion = presetJavaVersion
break
}
inputGradleVersionInts[i] < presetGradleVersionInts[i] -> {
break
}
i == presetGradleVersionInts.lastIndex -> {
maxJavaVersion = presetJavaVersion
}
}
}
}
return maxJavaVersion
}
} }
buildscript { buildscript {

View File

@@ -1,5 +1,5 @@
#Sat May 10 10:59:26 CST 2025 #Tue May 13 14:03:09 CST 2025
BUILD_TIME=1746845966689 BUILD_TIME=1747116189087
COMPILE_SDK_VERSION=35 COMPILE_SDK_VERSION=35
JAVA_VERSION=23 JAVA_VERSION=23
JAVA_VERSION_MIN_RADICAL=0 JAVA_VERSION_MIN_RADICAL=0
@@ -17,6 +17,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
TARGET_SDK_VERSION=35 TARGET_SDK_VERSION=35
TARGET_SDK_VERSION_INRT=29 TARGET_SDK_VERSION_INRT=29
VERSION_BUILD=3213 VERSION_BUILD=3216
VERSION_NAME=6.6.3 Alpha3 VERSION_NAME=6.6.3 Alpha3
VSCODE_EXT_REQUIRED_VERSION=1.0.8 VSCODE_EXT_REQUIRED_VERSION=1.0.8