From adf8dc9f30f0128c87edefc7c21400f7a536d597 Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Tue, 13 May 2025 18:49:00 +0800 Subject: [PATCH] =?UTF-8?q?6.6.3=20-=20Alpha3=20-=20Gradle=20=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E8=84=9A=E6=9C=AC=E6=8F=90=E5=8D=87=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E8=87=AA=E9=80=82=E5=BA=94=E8=83=BD=E5=8A=9B=20(discussion=20#?= =?UTF-8?q?369)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_zh-Hans.json | 7 +- .readme/README-ar.md | 2 +- .readme/README-en.md | 2 +- .readme/README-es.md | 2 +- .readme/README-fr.md | 2 +- .readme/README-ja.md | 2 +- .readme/README-ko.md | 2 +- .readme/README-ru.md | 2 +- .readme/README-zh-Hans.md | 16 +- .readme/README-zh-Hant-HK.md | 2 +- .readme/README-zh-Hant-TW.md | 2 +- README.md | 16 +- app/build.gradle.kts | 98 ++--- .../main/assets-app/doc/CHANGELOG-zh-Hans.md | 20 +- app/src/main/assets-app/doc/CHANGELOG.md | 20 +- gradle/wrapper/gradle-wrapper.properties | 4 +- .../internal/apk/v1/V1SchemeSigner.java | 24 +- .../internal/apk/v1/V1SchemeVerifier.java | 25 +- .../internal/util/X509CertificateUtils.java | 5 +- .../android/apksigner/PasswordRetriever.java | 7 +- settings.gradle.kts | 403 +++++++++++++----- version.properties | 6 +- 22 files changed, 429 insertions(+), 240 deletions(-) diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index 329f433a..58e0b917 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -1,7 +1,7 @@ { "$data": { "v6.6.3": { - "released_date": "2025/05/09", + "released_date": "2025/05/13", "feature": [ "版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据", "timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态", @@ -30,7 +30,8 @@ "打包单文件时自动读取并勾选已安装应用的声明权限 _[`issue #362`](http://issues.autojs6.com/362)_", "已忽略更新记录及客户端模式连接地址记录支持清空操作", "版本更新信息支持多语言显示 (与当前显示语言同步)", - "使用异步加载方式一定程度提升文件管理器列表滑动流畅性" + "使用异步加载方式一定程度提升文件管理器列表滑动流畅性", + "Gradle 构建脚本提升版本自适应能力 _[`discussion #369`](http://discussions.autojs6.com/369)_" ], "dependency": [ "本地化 Material Dialogs 版本 0.9.6.0", @@ -38,7 +39,7 @@ "附加 Jsoup 版本 1.19.1", "附加 Material Progressbar 版本 1.4.2", "附加 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" ] }, diff --git a/.readme/README-ar.md b/.readme/README-ar.md index 6e0ba871..4b62fd16 100644 --- a/.readme/README-ar.md +++ b/.readme/README-ar.md @@ -389,7 +389,7 @@ SDK Tools (أدوات SDK) (في النافذة اليمنى) يعتمد مشروع AutoJs6 على إصدار `JDK (مجموعة تطوير جافا)` بإصدار لا يقل عن `17`، ولكن يفضل الإصدار الذي لا يقل عن `19`. -اعتبارًا من 2 May 2025، الإصدار الأقصى المدعوم من JDK لمشروع AutoJs6 هو `24`. +اعتبارًا من 13 May 2025، الإصدار الأقصى المدعوم من JDK لمشروع AutoJs6 هو `24`. > ملاحظة: إذا كان نظام الكمبيوتر يحتوي على JDK والإصدار يفي بالمتطلبات المذكورة أعلاه، فيمكنك تخطي هذا القسم. diff --git a/.readme/README-en.md b/.readme/README-en.md index 9c7c11ec..5152e2d7 100644 --- a/.readme/README-en.md +++ b/.readme/README-en.md @@ -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. -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. diff --git a/.readme/README-es.md b/.readme/README-es.md index b5baadb1..f572de33 100644 --- a/.readme/README-es.md +++ b/.readme/README-es.md @@ -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`. -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. diff --git a/.readme/README-fr.md b/.readme/README-fr.md index fdfc013a..b7d623de 100644 --- a/.readme/README-fr.md +++ b/.readme/README-fr.md @@ -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`. -À 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. diff --git a/.readme/README-ja.md b/.readme/README-ja.md index b470a8cb..662d97f9 100644 --- a/.readme/README-ja.md +++ b/.readme/README-ja.md @@ -389,7 +389,7 @@ SDK Tools (SDK ツール) (右側のウィンドウにあります) AutoJs6プロジェクトが依存する `JDK (Java開発キット)` のリリースバージョンは少なくとも `17` で, それ以下のバージョンは推奨されませんが, 最低でも `19` の使用を推奨します. -2025 年 5 月 2 日 現在, AutoJs6がサポートする最大のJDKバージョンは `24` です. +2025 年 5 月 13 日 現在, AutoJs6がサポートする最大のJDKバージョンは `24` です. > 注: コンピュータシステムに適切なバージョンのJDKがインストールされている場合, この節の内容をスキップできます. diff --git a/.readme/README-ko.md b/.readme/README-ko.md index 95594716..515dddab 100644 --- a/.readme/README-ko.md +++ b/.readme/README-ko.md @@ -389,7 +389,7 @@ SDK Tools (SDK 도구) (오른쪽 창에 위치) AutoJs6 프로젝트는 `JDK (Java 개발 도구 키트)` 버전이 `17` 이상이어야 하지만, `19` 이상을 권장합니다. -2025 년 5 월 2 일 기준으로, AutoJs6이 지원하는 최대 JDK 버전은 `24`입니다. +2025 년 5 월 13 일 기준으로, AutoJs6이 지원하는 최대 JDK 버전은 `24`입니다. > 메모: 시스템에 JDK가 설치되어 있고, 버전이 위의 요구 사항을 충족하는 경우, 이 섹션을 건너뛸 수 있습니다. diff --git a/.readme/README-ru.md b/.readme/README-ru.md index 65ee6aa7..5d033c55 100644 --- a/.readme/README-ru.md +++ b/.readme/README-ru.md @@ -389,7 +389,7 @@ SDK Tools (SDK Инструменты) (находится в правом ок Для проекта AutoJs6 требуется версия `JDK (Java Development Kit)` не ниже `17`, но рекомендуется не ниже `19`. -По состоянию на 2 May 2025 года AutoJs6 поддерживает JDK максимальной версии `24`. +По состоянию на 13 May 2025 года AutoJs6 поддерживает JDK максимальной версии `24`. > Примечание: Если на компьютере уже установлен JDK и версия соответствует указанным требованиям, этот раздел можно пропустить. diff --git a/.readme/README-zh-Hans.md b/.readme/README-zh-Hans.md index 229ba602..a4e20e29 100644 --- a/.readme/README-zh-Hans.md +++ b/.readme/README-zh-Hans.md @@ -157,23 +157,33 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 # v6.6.3 -###### 2025/05/02 +###### 2025/05/13 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 +* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_ * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 +* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 +* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题 * `修复` 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)_ * `修复` README.md 中部分语言日期格式不正确的问题 -* `优化` 关于应用与开发者页面增加水平布局适配 +* `优化` 主题色扩充适配范围并支持更多控件类型 +* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性 +* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配 +* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项 +* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏 * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`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)_ # v6.6.2 @@ -320,7 +330,7 @@ SDK Tools (SDK 工具) (位于右侧窗口) AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`. -截至 2025 年 5 月 2 日, AutoJs6 可支持 JDK 最高版本为 `24`. +截至 2025 年 5 月 13 日, AutoJs6 可支持 JDK 最高版本为 `24`. > 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容. diff --git a/.readme/README-zh-Hant-HK.md b/.readme/README-zh-Hant-HK.md index ae8b492d..6adc5e22 100644 --- a/.readme/README-zh-Hant-HK.md +++ b/.readme/README-zh-Hant-HK.md @@ -389,7 +389,7 @@ SDK Tools (SDK 工具) (位於右側窗口) AutoJs6 項目依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`. -截至 2025 年 5 月 2 日, AutoJs6 可支持 JDK 最高版本為 `24`. +截至 2025 年 5 月 13 日, AutoJs6 可支持 JDK 最高版本為 `24`. > 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容. diff --git a/.readme/README-zh-Hant-TW.md b/.readme/README-zh-Hant-TW.md index 564704ea..40b58a13 100644 --- a/.readme/README-zh-Hant-TW.md +++ b/.readme/README-zh-Hant-TW.md @@ -389,7 +389,7 @@ SDK Tools (SDK 工具) (位於右側視窗) AutoJs6 專案依賴的 `JDK (Java 開發工具包)` 發行版本不低於 `17`, 但建議不低於 `19`. -截至 2025 年 5 月 2 日, AutoJs6 可支援 JDK 最高版本為 `24`. +截至 2025 年 5 月 13 日, AutoJs6 可支援 JDK 最高版本為 `24`. > 注: 如果計算機系統已安裝 JDK 且版本滿足上述要求, 則可跳過此小節內容. diff --git a/README.md b/README.md index 229ba602..a4e20e29 100644 --- a/README.md +++ b/README.md @@ -157,23 +157,33 @@ AutoJs6 在 Auto.js 最终项目的基础上, 于 `2021/12/01` 进行二次开 # v6.6.3 -###### 2025/05/02 +###### 2025/05/13 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 +* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_ * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 +* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 +* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题 * `修复` 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)_ * `修复` README.md 中部分语言日期格式不正确的问题 -* `优化` 关于应用与开发者页面增加水平布局适配 +* `优化` 主题色扩充适配范围并支持更多控件类型 +* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性 +* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配 +* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项 +* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏 * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`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)_ # v6.6.2 @@ -320,7 +330,7 @@ SDK Tools (SDK 工具) (位于右侧窗口) AutoJs6 项目依赖的 `JDK (Java 开发工具包)` 发行版本不低于 `17`, 但建议不低于 `19`. -截至 2025 年 5 月 2 日, AutoJs6 可支持 JDK 最高版本为 `24`. +截至 2025 年 5 月 13 日, AutoJs6 可支持 JDK 最高版本为 `24`. > 注: 如果计算机系统已安装 JDK 且版本满足上述要求, 则可跳过此小节内容. diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 38d041a0..bc227bd6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -732,7 +732,7 @@ android { // Configures multiple APKs based on ABI. 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)) } // 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 = "" 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 - while (niceVersionInt > javaVersionMinSupported) { - if (JvmTarget.values().any { it.name.contains(Regex("_$niceVersionInt$")) }) { + while (versionInt > javaVersionMinSupported) { + if (JvmTarget.values().any { it.name.contains(Regex("_$versionInt$")) }) { break } - niceVersionInt -= 1 + versionInt -= 1 isFallback = true } @@ -862,26 +877,20 @@ class Versions(filePath: String) { javaVersionInfoSuffix += " [fallback]" } - if (gradle.extra.has("gradleVersionToCoerceJavaVersion")) { - (gradle.extra["gradleVersionToCoerceJavaVersion"] as? String)?.let { - val maxGradleVersion = getMaxSupportedJavaVersion(it) - if (niceVersionInt > maxGradleVersion) { - niceVersionInt = maxGradleVersion - javaVersionInfoSuffix += " [coerced]" + if (versionInt > currentVersionInt) { + versionInt = currentVersionInt + javaVersionInfoSuffix += " [consistent-downgraded]" + } + + if (gradle.extra.has("javaVersionCoercedByGradle")) { + (gradle.extra["javaVersionCoercedByGradle"] as? Int)?.let { + if (versionInt > it) { + versionInt = it + javaVersionInfoSuffix += " [coercive-gradle-downgraded]" } } } - - if (niceVersionInt > currentVersionInt) { - niceVersionInt = currentVersionInt - javaVersionInfoSuffix += " [consistent]" - } - - gradle.beforeProject { - extensions.extraProperties["javaVersion"] = niceVersionInt - } - - JavaVersion.toVersion(niceVersionInt) + return versionInt } private var isBuildNumberAutoIncremented = false @@ -962,51 +971,6 @@ class Versions(filePath: String) { 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 = 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 { diff --git a/app/src/main/assets-app/doc/CHANGELOG-zh-Hans.md b/app/src/main/assets-app/doc/CHANGELOG-zh-Hans.md index 25709188..a639a995 100644 --- a/app/src/main/assets-app/doc/CHANGELOG-zh-Hans.md +++ b/app/src/main/assets-app/doc/CHANGELOG-zh-Hans.md @@ -6,26 +6,40 @@ # v6.6.3 -###### 2025/05/02 +###### 2025/05/13 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 +* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_ * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 +* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 +* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题 * `修复` 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)_ * `修复` README.md 中部分语言日期格式不正确的问题 -* `优化` 关于应用与开发者页面增加水平布局适配 +* `优化` 主题色扩充适配范围并支持更多控件类型 +* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性 +* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配 +* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项 +* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏 * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`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 +* `依赖` 附加 Material Progressbar 版本 1.4.2 * `依赖` 附加 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 diff --git a/app/src/main/assets-app/doc/CHANGELOG.md b/app/src/main/assets-app/doc/CHANGELOG.md index 25709188..a639a995 100644 --- a/app/src/main/assets-app/doc/CHANGELOG.md +++ b/app/src/main/assets-app/doc/CHANGELOG.md @@ -6,26 +6,40 @@ # v6.6.3 -###### 2025/05/02 +###### 2025/05/13 * `新增` 版本历史功能, 可查看发行版本历史更新记录 (多语言) 与统计数据 * `新增` timers.keepAlive 方法 (已全局化), 用于保持脚本活跃状态 * `新增` engines.on('start/stop/error', callback) 等事件监听方法, 用于监听脚本引擎全局事件 +* `新增` images.detectMultiColors 方法, 用于多点颜色校验 _[`issue #374`](http://issues.autojs6.com/374)_ * `修复` 主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题 * `修复` 部分设备代码编辑器空行显示方框字符的问题 * `修复` 主题色设置页面调色盘对话框可能无限叠加的问题 * `修复` 无障碍服务关闭时音量加键停止所有脚本功能失效的问题 +* `修复` 定时任务页面编辑自定义广播内容时出现的输入法遮挡问题 * `修复` APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题 +* `修复` Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题 * `修复` 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)_ * `修复` README.md 中部分语言日期格式不正确的问题 -* `优化` 关于应用与开发者页面增加水平布局适配 +* `优化` 主题色扩充适配范围并支持更多控件类型 +* `优化` 主页抽屉在横向屏幕或超宽屏幕的宽度适应性 +* `优化` 关于应用与开发者页面增加水平布局及小屏布局适配 +* `优化` 设置页面对话框相关设置支持 "使用默认值" 菜单选项 +* `优化` 文件管理器浮动按钮展开后点击其他区域可自动隐藏 * `优化` 打包单文件时自动读取并勾选已安装应用的声明权限 _[`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 +* `依赖` 附加 Material Progressbar 版本 1.4.2 * `依赖` 附加 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5c1b2bfe..67959a47 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Apr 18 11:53:53 CST 2025 +#Tue May 13 17:11:16 CST 2025 distributionBase=GRADLE_USER_HOME 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 zipStorePath=wrapper/dists diff --git a/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java b/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java index 35f051cd..0aab8ae9 100644 --- a/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java +++ b/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java @@ -386,9 +386,7 @@ public abstract class V1SchemeSigner { checkEntryNameValid(entryName); byte[] entryDigest = jarEntryDigests.get(entryName); Attributes entryAttrs = new Attributes(); - String encodedEntryDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - ? Base64.getEncoder().encodeToString(entryDigest) - : com.mcal.apksigner.utils.Base64.encode(entryDigest); + String encodedEntryDigest = base64EncodeCompat(entryDigest); entryAttrs.putValue(entryDigestAttributeName, encodedEntryDigest); ByteArrayOutputStream sectionOut = new ByteArrayOutputStream(); byte[] sectionBytes; @@ -409,6 +407,18 @@ public abstract class V1SchemeSigner { 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 { // 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 @@ -460,9 +470,7 @@ public abstract class V1SchemeSigner { // Add main attribute containing the digest of MANIFEST.MF. MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm); - String encodedManifestDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - ? Base64.getEncoder().encodeToString(md.digest(manifest.contents)) - : com.mcal.apksigner.utils.Base64.encode(md.digest(manifest.contents)); + String encodedManifestDigest = base64EncodeCompat(md.digest(manifest.contents)); mainAttrs.putValue(getManifestDigestAttributeName(manifestDigestAlgorithm), encodedManifestDigest); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { @@ -477,9 +485,7 @@ public abstract class V1SchemeSigner { byte[] sectionContents = manifestSection.getValue(); byte[] sectionDigest = md.digest(sectionContents); Attributes attrs = new Attributes(); - String encodedSectionDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - ? Base64.getEncoder().encodeToString(sectionDigest) - : com.mcal.apksigner.utils.Base64.encode(sectionDigest); + String encodedSectionDigest = base64EncodeCompat(sectionDigest); attrs.putValue(entryDigestAttributeName, encodedSectionDigest); try { diff --git a/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java b/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java index f3fd6415..df39cc08 100644 --- a/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java +++ b/modules/apk-signer/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java @@ -17,6 +17,8 @@ package com.android.apksig.internal.apk.v1; 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.pkcs7.AlgorithmIdentifier.getJcaDigestAlgorithm; 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.util.ArrayList; import java.util.Arrays; -import java.util.Base64; -import java.util.Base64.Decoder; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -971,8 +971,8 @@ public abstract class V1SchemeVerifier { V1SchemeConstants.MANIFEST_ENTRY_NAME, jcaDigestAlgorithm, mSignatureFileEntry.getName(), - Base64.getEncoder().encodeToString(actual), - Base64.getEncoder().encodeToString(expected)); + base64EncodeCompat(actual), + base64EncodeCompat(expected)); verified = false; } } @@ -1013,8 +1013,8 @@ public abstract class V1SchemeVerifier { Issue.JAR_SIG_MANIFEST_MAIN_SECTION_DIGEST_DID_NOT_VERIFY, jcaDigestAlgorithm, mSignatureFileEntry.getName(), - Base64.getEncoder().encodeToString(actual), - Base64.getEncoder().encodeToString(expected)); + base64EncodeCompat(actual), + base64EncodeCompat(expected)); } } } @@ -1066,8 +1066,8 @@ public abstract class V1SchemeVerifier { entryName, jcaDigestAlgorithm, mSignatureFileEntry.getName(), - Base64.getEncoder().encodeToString(actual), - Base64.getEncoder().encodeToString(expected)); + base64EncodeCompat(actual), + base64EncodeCompat(expected)); } } } @@ -1142,7 +1142,6 @@ public abstract class V1SchemeVerifier { String digestAttrSuffix, int minSdkVersion, int maxSdkVersion) { - Decoder base64Decoder = Base64.getDecoder(); List result = new ArrayList<>(1); if (minSdkVersion < AndroidSdkVersion.JELLY_BEAN_MR2) { // 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; } // Supported digest algorithm - result.add(new NamedDigest(alg, base64Decoder.decode(digestBase64))); + result.add(new NamedDigest(alg, base64DecodeCompat(digestBase64))); break; } // 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 continue; } - byte[] digest = base64Decoder.decode(digestBase64); + byte[] digest = base64DecodeCompat(digestBase64); byte[] digestInResult = getDigest(result, alg); if ((digestInResult == null) || (!Arrays.equals(digestInResult, digest))) { result.add(new NamedDigest(alg, digest)); @@ -1373,8 +1372,8 @@ public abstract class V1SchemeVerifier { entryName, expectedDigest.jcaDigestAlgorithm, V1SchemeConstants.MANIFEST_ENTRY_NAME, - Base64.getEncoder().encodeToString(actualDigest), - Base64.getEncoder().encodeToString(expectedDigest.digest)); + base64EncodeCompat(actualDigest), + base64EncodeCompat(expectedDigest.digest)); } } } diff --git a/modules/apk-signer/src/main/java/com/android/apksig/internal/util/X509CertificateUtils.java b/modules/apk-signer/src/main/java/com/android/apksig/internal/util/X509CertificateUtils.java index ca6271df..07080cff 100644 --- a/modules/apk-signer/src/main/java/com/android/apksig/internal/util/X509CertificateUtils.java +++ b/modules/apk-signer/src/main/java/com/android/apksig/internal/util/X509CertificateUtils.java @@ -16,6 +16,8 @@ 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.Asn1DecodingException; 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.X509Certificate; import java.util.ArrayList; -import java.util.Base64; import java.util.Collection; /** @@ -265,7 +266,7 @@ public class X509CertificateUtils { + "valid certificate footer"); } } - byte[] derEncoding = Base64.getDecoder().decode(pemEncoding.toString()); + byte[] derEncoding = base64DecodeCompat(pemEncoding.toString()); // consume any trailing whitespace in the byte buffer int nextEncodedChar = certificateBuffer.position(); while (certificateBuffer.hasRemaining()) { diff --git a/modules/apk-signer/src/main/java/com/android/apksigner/PasswordRetriever.java b/modules/apk-signer/src/main/java/com/android/apksigner/PasswordRetriever.java index ed6927bb..8ce5dd0d 100644 --- a/modules/apk-signer/src/main/java/com/android/apksigner/PasswordRetriever.java +++ b/modules/apk-signer/src/main/java/com/android/apksigner/PasswordRetriever.java @@ -16,6 +16,8 @@ package com.android.apksigner; +import android.annotation.SuppressLint; + import java.io.ByteArrayOutputStream; import java.io.Console; import java.io.File; @@ -86,7 +88,7 @@ public class PasswordRetriever implements AutoCloseable { return encoded; } - private static char[] decodePassword(byte[] pwdBytes, Charset encoding) throws IOException { + private static char[] decodePassword(byte[] pwdBytes, Charset encoding) throws IOException { CharBuffer pwdChars = encoding.newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) @@ -140,6 +142,7 @@ public class PasswordRetriever implements AutoCloseable { } String consoleCharsetName = null; try { + @SuppressLint("SoonBlockedPrivateApi") Method encodingMethod = Console.class.getDeclaredMethod("encoding"); encodingMethod.setAccessible(true); consoleCharsetName = (String) encodingMethod.invoke(null); @@ -314,7 +317,7 @@ public class PasswordRetriever implements AutoCloseable { if (value == null) { throw new IOException( "Failed to read " + description + ": environment variable " + value - + " not specified"); + + " not specified"); } return getPasswords(value.toCharArray(), additionalPwdEncodings); } else { diff --git a/settings.gradle.kts b/settings.gradle.kts index 50644f5d..f7f3775d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,30 +1,5 @@ @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( "jieba-analysis", "apk-signer", @@ -67,9 +42,103 @@ modules.forEach { 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 + // @Reference gradle--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> = 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 + // @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 + // @Reference https://developer.android.com/build/releases/gradle-plugin#updating-gradle + // @Updated by SuperMonster003 on May 13, 2025. + val agpGradleCompatibility: List> = 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 = 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 IDENTIFIER_FALLBACK = "fallback" - val IDENTIFIER_UNKNOWN = "unknown" val DEFAULT_VERSION = "0" } @@ -134,41 +203,36 @@ pluginManagement { /* Print concerned info by `System.getProperties()`. */ val isShowConcernedSystemProperties = true - /* https://docs.gradle.org/current/userguide/compatibility.html . */ - val isJavaVersionCoercedByGradleVersion = true - val isCleanupPaddleOcr = false val isCleanupRapidOcr = false - val fallbackGradleVersion = "8.0.2" - val fallbackKotlinVersion = "1.9.22" - val recommendedMinGradleVersion = "8.5.2" - val recommendedMinKotlinVersion = "1.9.24" + val fallbackAgpVersion = "7.4.2" + val fallbackKotlinVersion = "1.7.10" @Suppress("unused") val platforms = object { val androidStudio = object : Platform( name = "AndroidStudio", vendor = "Google", - androidVersionMap = mapOf( - "2025.1" to "8.10.0-rc02", /* Apr 11, 2025. */ - "2024.3" to "8.9.1", /* Apr 11, 2025. */ - "2024.2" to "8.8.0", /* Jan 13, 2025. */ - "2024.1" to "8.6.0", /* Aug 30, 2024. */ - "2023.3" to "8.5.0-alpha02", /* Mar 28, 2024. */ - "2023.2" to "8.3.0-rc02", /* Feb 14, 2024. */ + // @Reference https://developer.android.com/studio/releases#android_gradle_plugin_and_android_studio_compatibility + // @Updated by SuperMonster003 on May 13, 2025. + agpVersionMap = mapOf( + "2025.1" to "8.10.0", /* May 13, 2025. */ + "2024.3" to "8.9.2", /* Apr 11, 2025. */ + "2024.2" to "8.7.3", /* Jan 13, 2025. */ + "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. */ "2022.3" to "8.1.4", /* Mar 31, 2024. */ "2022.2" to "8.0.2", /* May 26, 2023. */ "2022.1" to "7.4.2", /* Mar 25, 2023. */ - consts.IDENTIFIER_FALLBACK to fallbackGradleVersion, ), + // @Updated by SuperMonster003 on May 13, 2025. kotlinVersionMap = mapOf( - "2025.1" to "2.1.20", /* Apr 11, 2025. */ "2024.3" to "2.1.20", /* Apr 11, 2024. */ "2024.2" to "2.1.0", /* Nov 29, 2024. */ "2024.1" to "2.0.0", /* Aug 13, 2024. */ - consts.IDENTIFIER_FALLBACK to fallbackKotlinVersion, ), codenameVersionMap = mapOf( "2025.1" to "N", /* Apr 11, 2025. */ @@ -196,9 +260,11 @@ pluginManagement { "D" to "Dolphin", /* Born on Jan 31, 2022. */ "C" to "Chipmunk", /* Born on Oct 13, 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", "R" to "Rhino", "S" to "Snail", "T" to "Tiger", @@ -220,7 +286,8 @@ pluginManagement { val intelliJIdea = object : Platform( name = "IntelliJIdea", vendor = "Jetbrains", - androidVersionMap = mapOf( + // @Updated by SuperMonster003 on Apr 23, 2025. + agpVersionMap = mapOf( "2025.1" to "8.9.2", /* Apr 23, 2025. */ "2024.3.1" to "8.7.3", /* Dec 10, 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.1" to "7.4.2", /* May 26, 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( "2025.1" to "2.1.20", /* Apr 12, 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.1" to "1.9.24", /* Dec 3, 2024. */ "2023.3" to "1.9.23", /* Mar 29, 2024. */ - consts.IDENTIFIER_FALLBACK to fallbackKotlinVersion, ), ) { override val weight = 10 @@ -248,15 +314,13 @@ pluginManagement { val temurin = object : Platform( name = "Temurin", vendor = "temurin", /* More common as "Eclipse Adoptium". */ - androidVersionMap = mapOf( + agpVersionMap = mapOf( "21.0.6+7" to "8.7.3", /* Apr 16, 2025. */ "20.0.2+9" to "8.2.2", /* Dec 2, 2024. */ - consts.IDENTIFIER_FALLBACK to recommendedMinGradleVersion, ), kotlinVersionMap = mapOf( "21.0.6+7" to "2.1.10", /* Apr 16, 2025. */ "20.0.2+9" to "1.9.24", /* Dec 2, 2024. */ - consts.IDENTIFIER_FALLBACK to recommendedMinKotlinVersion, ), ) { override val weight = 5 @@ -264,13 +328,7 @@ pluginManagement { } val unknown = object : Platform( - name = "Unknown", vendor = consts.IDENTIFIER_UNKNOWN, - androidVersionMap = mapOf( - consts.IDENTIFIER_FALLBACK to recommendedMinGradleVersion, - ), - kotlinVersionMap = mapOf( - consts.IDENTIFIER_FALLBACK to recommendedMinKotlinVersion, - ), + name = "Unknown", vendor = "unknown", ) { fun declare() = systemProperties.platform?.let { 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( - Classpath(id = "com.android.tools.build:gradle", version = "auto:android"), - Classpath(id = "org.jetbrains.kotlin:kotlin-gradle-plugin", version = "auto:kotlin"), - Plugin(id = "com.google.devtools.ksp", version = "auto:ksp"), + Classpath(id = "com.android.tools.build:gradle", version = overriddenAgpVersion ?: "auto:agp"), + Classpath(id = "org.jetbrains.kotlin:kotlin-gradle-plugin", version = overriddenKotlinVersion ?: "auto:kotlin"), + 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( + "2.2.0-Beta2" to "2.0.1", /* May 2, 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.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-RC2" to "1.0.31", /* Mar 7, 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.0" to "1.0.9", /* 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( var name: String, val vendor: String, - val androidVersionMap: Map, - val kotlinVersionMap: Map, + val agpVersionMap: Map = emptyMap(), + val kotlinVersionMap: Map = emptyMap(), val codenameVersionMap: Map? = null, val codenameMap: Map? = null, ) { @@ -438,16 +498,21 @@ pluginManagement { // ! zh-CN: // ! Fallback (回退) 是一种临时或替代的解决方法, 用于应对功能不可用的特定情况. // ! Compatibility (兼容) 是一种更广泛的设计原则, 确保新版本能兼容并继续支持旧版本的操作和数据. - val fallback = consts.IDENTIFIER_FALLBACK - val compatible = "compatible" + val fallback = "fallback" + + val upgraded = "upgraded" + val downgraded = "downgraded" + val nearestLowerMatched = "nearest-lower-matched" val specified = "specified" val auto = "auto" val fallbackSuffix = " [$fallback]" - val compatibleSuffix = " [$compatible]" - val specifiedSuffix = " [$specified]" + val upgradedSuffix = " [$upgraded]" + val downgradedSuffix = " [$downgraded]" + val nearestLowerMatchedSuffix = " [$nearestLowerMatched]" val autoSpecifiedSuffix = " [$auto-$specified]" + val userSpecifiedSuffix = " [user-$specified]" } @@ -474,7 +539,69 @@ pluginManagement { 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) -> Map> = mapOf( "ksp" to { versionMap: Map -> @@ -484,94 +611,90 @@ pluginManagement { .find { it.id.contains("kotlin-gradle-plugin", true) } ?.takeIf { !it.version.startsWith("${identifier.auto}:") } ?.version?.let { kt -> - suffix += identifier.autoSpecifiedSuffix versionMap[kt]?.let { kt } } - ?: Version(kotlinVersionMap, platform.version).bestMatchingValue - ?: kotlinVersionMap[identifier.fallback]?.let { kt -> + ?: versions.kotlin.bestMatchingValue?.also { + suffix += identifier.autoSpecifiedSuffix + } + ?: versions.kotlin.fallbackVersion?.let { kt -> suffix += identifier.fallbackSuffix versionMap[kt]?.let { kt } } val kspVersion = kotlinVersion?.let { kt -> val ver = Version(config.kspVersionMap, kt) - ver.bestMatchingKey?.let { key -> - if (ver.isBestMatchingOperated) suffix += identifier.compatibleSuffix - "$key-${ver.bestMatchingValue}" - } + val key = ver.bestMatchingKey ?: return@let null + val value = ver.bestMatchingValue ?: return@let null + ver.bestMatchingOperationHintSuffix?.let { suffix += it } + "$key-$value" } mapOf("version" to kspVersion, "suffix" to suffix) }, ) - val classpath = config.libs.filterIsInstance().map { + val classpath = config.libs.filterIsInstance().map { lib -> var suffix = "" val version: String = when { - it.version.startsWith("${identifier.auto}:") -> { - val mapType = it.version.substring("${identifier.auto}:".length) - val map = when (mapType) { - "android" -> platform.androidVersionMap - "kotlin" -> platform.kotlinVersionMap - else -> throw Exception("Unknown version ${it.version} for classpath ${it.id}") + lib.version.startsWith("${identifier.auto}:") -> { + val mapType = lib.version.substring("${identifier.auto}:".length) + val ver = when (mapType) { + "agp" -> versions.agp + "kotlin" -> versions.kotlin + else -> throw Exception("Unknown version ${lib.version} for classpath ${lib.id}") } - val ver = Version(map, platform.version) - ver.bestMatchingKey?.let { - if (ver.isBestMatchingOperated) suffix += identifier.compatibleSuffix - ver.bestMatchingValue - } ?: map[identifier.fallback]?.also { + ver.bestMatchingValue?.also { + ver.bestMatchingOperationHintSuffix?.let { s -> suffix += s } + } ?: ver.fallbackVersion?.also { suffix += identifier.fallbackSuffix } ?: consts.DEFAULT_VERSION } - else -> it.version.also { - suffix += identifier.specifiedSuffix + else -> lib.version.also { + suffix += identifier.userSpecifiedSuffix } } - if (config.isJavaVersionCoercedByGradleVersion && it.id == "com.android.tools.build:gradle") { - gradle.extra.set("gradleVersionToCoerceJavaVersion", version) + if (lib.id == "com.android.tools.build:gradle") { + 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" } } - val plugins = config.libs.filterIsInstance().map { + val plugins = config.libs.filterIsInstance().map { lib -> var suffix = "" val version: String = when { - it.version.startsWith("${identifier.auto}:") -> { - val automator = pluginVersionAutomatorMap[it.version.substring("${identifier.auto}:".length)]!! + lib.version.startsWith("${identifier.auto}:") -> { + val automator = pluginVersionAutomatorMap[lib.version.substring("${identifier.auto}:".length)]!! val result = automator.invoke(config.kspVersionMap) 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 -> { - suffix += identifier.specifiedSuffix - it.version + suffix += identifier.userSpecifiedSuffix + lib.version } } - console.versionInfo += "Plugin: \"${it.id}:$version\"$suffix" - mapOf("id" to it.id, "version" to version, "isApply" to it.isApply) + console.versionInfo += "Plugin: \"${lib.id}:$version\"$suffix" + mapOf("id" to lib.id, "version" to version, "isApply" to lib.isApply) } - private inner class Version(private val map: Map, platformVersion: String) { + private open inner class Version(val map: Map, platformVersion: String, val fallbackVersion: String? = null) { - val bestMatchingKey: String? - val bestMatchingValue: String? - val isBestMatchingOperated: Boolean + val bestMatchingKey: String? = findBestMatchingMapKey(platformVersion) - init { - bestMatchingKey = findBestMatchingMapKey(platformVersion) - bestMatchingValue = bestMatchingKey?.let { map[it] } - isBestMatchingOperated = bestMatchingKey != null && bestMatchingKey != platformVersion + var bestMatchingOperationHintSuffix: String? = identifier.nearestLowerMatchedSuffix.takeIf { + 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 sortedVersions = map.keys.filter { it != identifier.fallback }.sortedWith { v1, v2 -> - val (ver1Numbers, ver1Suffix) = toVersionParts(v1) - val (ver2Numbers, ver2Suffix) = toVersionParts(v2) - compareVersionParts(ver2Numbers, ver1Numbers).takeIf { it != 0 } ?: compareSuffix(ver2Suffix, ver1Suffix) - } + val sortedVersions = map.keys.filter { it != identifier.fallback }.sortedWith(::compareVersionStrings).reversed() for (version in sortedVersions) { val (versionNumbers, versionSuffix) = toVersionParts(version) val versionComparisonScore = compareVersionParts(versionNumbers, platformVersionNumbers) @@ -585,6 +708,14 @@ pluginManagement { 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, parts2: List): Int { for (i in 0 until maxOf(parts1.size, parts2.size)) { 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 = 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 { diff --git a/version.properties b/version.properties index f6ae261e..08592102 100644 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ -#Sat May 10 10:59:26 CST 2025 -BUILD_TIME=1746845966689 +#Tue May 13 14:03:09 CST 2025 +BUILD_TIME=1747116189087 COMPILE_SDK_VERSION=35 JAVA_VERSION=23 JAVA_VERSION_MIN_RADICAL=0 @@ -17,6 +17,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 TARGET_SDK_VERSION=35 TARGET_SDK_VERSION_INRT=29 -VERSION_BUILD=3213 +VERSION_BUILD=3216 VERSION_NAME=6.6.3 Alpha3 VSCODE_EXT_REQUIRED_VERSION=1.0.8