Gradle与JDK版本不匹配?定位原因与四种修复方案详解
早上拉下来一个老项目的代码导入Android Studio一运行就给我甩出一行提示Gradle版本和Java版本不匹配。这种报错在安卓开发里简直是家常便饭尤其是当你刚换电脑、刚升级IDE、或者刚clone了同事的旧仓库。很多人遇到之后第一反应就是去网上搜怎么降版本怎么升JDK搜了半天还是一头雾水最后只能瞎改配置碰运气。这篇文章我不会绕弯子直接把这个问题的本质讲清楚为什么Gradle和JDK必须匹配怎么从项目三个配置文件里快速定位真实的版本组合再给出四种靠谱的解决方案到底怎么选。内容同样适合刚入行的新手——即使你还没搞懂Gradle和JDK的关系照着步骤操作也能解决也适合有经验的老手——我最后会放一些团队协作和缓存处理的实战细节避免你踩坑。1. 版本不匹配的本质Gradle是JVM世界的挑食者很多新手会把Gradle当成安卓项目的一种构建工具就完事了实际上Gradle本身就是一个运行在JVM上的程序。既然是JVM程序它就必须依赖某个Java运行时环境JDK或JRE才能启动。关键在于Gradle对不同版本的Java字节码有明确的兼容范围一旦你给Gradle喂了一个它不认识的JDK版本它直接罢工。1.1 从一次具体报错看问题本质最常见的报错长这样Unsupported class file major version 55这个55是Java字节码的class file major version编号。Java 8对应52Java 11对应55Java 17对应61。如果Gradle版本太旧无法读取新JDK编译出来的class文件就会抛这个错。还有另一种常见错误Could not determine java version from 17.0.2或者干脆是Gradle启动时找不到JAVA_HOME。这些报错背后的逻辑都一样你手里的JDK版本和Gradle支持的JDK范围不在一个区间里。1.2 Gradle与JDK兼容性对照我在实际使用中整理过一张兼容表你可以直接保存下来排查问题的时候对着看Gradle版本最低JDK版本最高支持JDK版本4.xJDK 8JDK 105.xJDK 8JDK 126.xJDK 8JDK 146.7可支持157.0–7.2JDK 8JDK 167.3JDK 8JDK 178.xJDK 8JDK 198.5JDK 8JDK 21这张表仅供快速参考实际以Gradle官方发布的兼容性文档为准。但你已经能看出来如果你用的是Gradle 6.0却装了JDK 17那报错几乎是必然的。反过来说如果你用Gradle 8.0搭配JDK 8虽然不报错但某些新特性用不了属于能跑但不是最优解。1.3 AGP安卓Gradle插件在其中扮演的角色还有一个变量容易被忽略AGP。AGP是安卓项目里用来跟Gradle配合的插件它的版本号同样对Gradle和JDK有硬性要求。很多版本不匹配的报错表面上是java与gradle版本不匹配实际上是AGP版本配错了。常见的对应关系是这样AGP版本要求的Gradle最低版本要求的JDK最低版本4.2.06.7.1JDK 87.07.0.2JDK 117.47.5JDK 118.08.0JDK 17所以你在查问题的时候不能只看Gradle和JDK还要把AGP也算进去。很多项目报错java与gradle版本不匹配真正的根源是AGP升级之后没同步升级Gradle或者反过来。2. 完整排查链路三分钟锁定你的真实版本组合知道了因果关系接下来就是实操。遇到这类报错不要急着改配置先花三分钟把项目当前的版本组合彻底摸清楚。我见过太多人乱改一通最后把能跑的项目改坏了。2.1 第一步从三个配置文件确认Gradle版本安卓项目的Gradle版本藏在两个文件里一个是 wrapper 配置一个是 IDE 配置。第一个文件是gradle/wrapper/gradle-wrapper.properties打开之后找到distributionUrl这一行distributionUrlhttps\://services.gradle.org/distributions/gradle-6.7.1-all.zip这里的gradle-6.7.1就是项目实际使用的Gradle版本。第二个文件是项目根目录的build.gradle里面会声明AGP版本dependencies { classpath com.android.tools.build:gradle:4.1.0 }这个4.1.0是AGP版本。如果你用了Kotlin还要注意Kotlin插件版本不过它通常不影响JDK兼容问题。第三个文件是app/build.gradle或者模块目录下的build.gradle里面有一块android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }这个VERSION_1_8是代码编译时生成的字节码级别如果你的JDK是17但这里写了1_8往往也会触发不匹配。2.2 第二步确认JDK版本和Android Studio的JBR接下来确认JDK。Android Studio从3.0开始自带一个JBRJetBrains Runtime本质上是个定制版JDK。你打开Android Studio进入File Project Structure SDK Location能找到一个叫JDK Location的设置项。很多项目默认会指向IDE自带的JBR但如果你在全局设置了JAVA_HOMEIDE又使用了外部JDK这就容易乱。更直接的方法是打开命令行进入项目根目录运行java -version再看一下echo $JAVA_HOMEWindows上是echo %JAVA_HOME%。这两个输出来的是你当前终端环境里的JDK版本。需要注意的是Android Studio里的Gradle JDK不一定等同于这个终端版本它有独立配置入口。在最新版Android Studio里路径是Settings Build, Execution, Deployment Build Tools Gradle里面有个Gradle JDK下拉框这里显示的才是真正用来跑Gradle的JDK版本。把这几个信息全部记下来。2.3 第三步用一条命令快速验证如果嫌上面两步麻烦我分享一个我平时最常用的诊断命令直接在项目根目录执行./gradlew -v这样能一次性打印出Gradle版本、JVM版本和操作系统信息。比如输出Gradle 6.7.1 JVM: 17.0.2 (Oracle Corporation 17.0.28)看到这里我心里基本就有数了Gradle 6.7.1理论上最多到JDK 15你现在是JDK 17百分之百会报版本不匹配。2.4 一个刚遇到的实际排查案例前两周有个同事找我说拉了一个新项目执行./gradlew assembleDebug直接报错。我一问他说Android Studio版本是2023.1也就是新北极狐项目用的AGP是7.4。我让他先跑./gradlew -v输出显示Gradle 7.5、JVM 17。查一下AGP 7.4和Gradle 7.5的搭配要求JDK是11以上17是可以的理论上应该没问题。但他报错内容是Unsupported class file major version 61。这说明有某个module还是用旧的方式读取字节码。我继续检查发现他的某个第三方Library模块根目录下还有一个独立的build.gradle里面强制写了sourceCompatibility JavaVersion.VERSION_17而主工程依赖了一个旧Gradle的wrapper。破案了Gradle 7.5本身支持JDK 17但这个外部库代码是用JDK 17编译的Gradle 7.5读不了。所以说版本不匹配有时候不是全局不匹配而是局部字节码级别不匹配。这个案例提醒我一个重要点排查不要只盯着全局版本还要看模块级的编译配置。3. 四种解决方案怎么选、怎么做、为什么排查清楚了就该动手修复。同样是版本不匹配不同场景适合不同方案。我按优先级给你梳理四套做法每一套都写上适用场景和具体配置。3.1 方案一调整gradle-wrapper.properties里的Gradle版本这应该是你想到的第一个方案。如果你的项目Gradle版本太旧、而JDK太新最省事的做法就是把Gradle升级或降级到兼容某个JDK的版本。比如你环境变量里只有JDK 17那就把Gradle从6.7.1改到7.3以上。操作方式是打开gradle/wrapper/gradle-wrapper.properties把distributionUrl里的版本号改掉distributionUrlhttps\://services.gradle.org/distributions/gradle-7.3-all.zip然后回Android Studio执行一次Sync Now让Gradle重新下载、重新包装。这里有个很多人都踩过的坑改完gradle-wrapper.properties之后如果IDE还报错你必须格外留意该项目的Gradle是否真的被wrapper接管了。去Settings Build, Execution, Deployment Build Tools Gradle看右侧的Use Gradle from选项。如果你选了Specified location而不是gradle-wrapper.properties那你改了wrapper也没用IDE还是会用你手动指定的那个Gradle路径。3.2 方案二切换JDK版本推荐用Android Studio自带JBR如果你的项目Gradle版本很老比如4.x而你的电脑只装了JDK 17那与其冒着大版本升级的风险去改Gradle不如把JDK切回8或11。我特别建议你直接在Android Studio里设置Gradle JDK。打开Settings Build, Execution, Deployment Build Tools Gradle在Gradle JDK下拉框里选择JDK 11或者JDK 8这比去系统里卸掉旧JDK要安全得多。因为Android Studio自带JBR里通常包含多个版本选项你可以直接选一个新旧合适的版本互不影响。选完之后记得跑一遍./gradlew -v确认现在的JVM版本到底是什么。我在项目里试过多次遇到Gradle 5.1.1和JDK 17只要切到JDK 11同步率几乎100%。3.3 方案三升级AGP并联动修改compileOptions很多时候你其实不需要动Gradle只升级AGP就够了。AGP 7.0以上的插件会要求Gradle 7.0如果你现在项目用的是AGP 4.2、Gradle 6.7.1想用JDK 11的话建议直接升级AGP。在项目根目录的build.gradle里修改dependencies { classpath com.android.tools.build:gradle:7.0.2 }然后在gradle-wrapper.properties里把Gradle版本提到7.0.2以上distributionUrlhttps\://services.gradle.org/distributions/gradle-7.0.2-all.zip接着回到app/build.gradle里补上或修改编译选项android { compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } }这一步很多人会漏掉。升级AGP之后如果还写着VERSION_1_8代码虽然能编译但当你用到一些依赖了Java 11 API的库运行期就会触发不匹配。升级AGP的目的不只是迎合JDK更是让整个构建链路统一到同一套字节码级别上。3.4 方案四全局配置gradle.properties指定JAVA_HOME这是一套偏野路子但意外好用的办法。如果你手上有多个项目每个需要的Gradle版本不一样切来切去太烦你可以考虑在gradle.properties里强制指定项目要用的JDK路径。在项目根目录的gradle.properties里加一行org.gradle.java.home/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/HomeWindows上写成org.gradle.java.homeC:\\Program Files\\Java\\jdk-11.0.2。这样做的好处是就算你系统全局JAVA_HOME指向17这个项目跑Gradle时还是会用指定的11。适合那种这个项目就是只能用JDK 8跑的顽固老项目。需要注意的是这个路径必须真实存在IDE无法校验路径对不对。路径写错的话Gradle启动时会直接报Invalid Java home而且报错信息不会提示你哪里写错了只能自己检查拼写。3.5 四套方案的适用场景对比方案适用场景优点潜在坑改Gradle版本项目结构较新JDK太新而Gradle旧改动小一条URL搞定Gradle过大版本升级可能连带AGP报错切JDK版本老项目居多系统鼓励用老JDK不用改构建脚本IDE操作即可外部库内置的字节码级别可能仍不兼容升级AGP项目太老AGP/Gradle都低于现代要求一劳永逸兼容新版IDE需要同时调整多个文件容易遗漏指定JDK路径顽固项目不想为它动全局环境隔离性好多项目互不干扰路径配置不灵活换电脑又要改4. 实战里最容易中招的四个细节版本不匹配这个报错我遇到太多次了。很多时候不是你不会改而是有一个隐藏的干扰项挡住你的去路。下面这四件事算是我这几年踩出来的血泪经验。4.1 下载Gradle太慢用离线包避开龟速网络当你改了wrapper里的Gradle版本需要重新下载。安卓开发在国内最头痛的就是下载Gradle动不动就卡在一个Downloading gradle-7.3-all.zip的进度条上。我自己的经验是直接用离线包是最省时的。先把zip手动下载好放到一个你记得住的目录例如E:\gradle-dist\然后在gradle-wrapper.properties里把路径改成本地路径distributionUrlfile\:/E:/gradle-dist/gradle-7.3-all.zip或者更好的做法是把zip放到~/.gradle/wrapper/dists/下面让Gradle自动解压。这个目录的具体结构是按版本名和哈希值分级的不推荐手动塞容易搞错。更常规的做法是直接在Android Studio的Settings Build, Execution, Deployment Build Tools Gradle里把Distribution改为Local distribution directory然后选中你之前解压好的Gradle目录。这样完全绕开网络。4.2 Gradle和IDE缓存改完配置仍然报错的元凶改完版本后如果同步或者编译仍然报版本不匹配很多时候是缓存造成。Gradle和Android Studio都有一层构建缓存它们缓存了你之前的编译参数和类路径。这时候你需要做两件事第一执行一次clean在Terminal里跑./gradlew clean第二如果clean后还是老报错就去File Invalidate Caches / Restart...勾选Clear file system cache and Local History重启IDE。这一步会清除掉IDE对项目的索引尤其是当你改了JDK路径或Gradle版本之后IDE里的旧索引会让报错区域显示错误的信息。我见过一个真实例子同事明明已经在gradle-wrapper.properties里改成7.3了但IDE一直提示他项目用的是6.1.1。查了半天发现他在Settings Gradle里选的是Specified location指向了一个旧的Gradle目录。这种表面上改了、实际没接管的坑特别隐蔽所以再次强调改配置文件之后必须去IDE的设置里确认当前生效的Gradle来源。4.3 团队协作用同一套版本锁定避免环境差异版本不匹配的另一个高发场景是团队协作。你同事开发得好好的项目你拉下来就跑不了十有八九是本地JDK版本和Gradle版本不一样。要解决这个事光靠口头沟通不现实得靠配置文件锁定。我建议在项目根目录放一个gradle.properties在里面强制写死JDK路径或者统一约束gradle版本。更常见的是把gradle-wrapper.properties提交到git仓库这样团队成员拉下来之后都会使用同一个Gradle版本。我曾经在一个多模块项目里吃过亏合并代码时有人把wrapper文件加了gitignore结果五个成员里三个报版本不匹配排查了一下午。还有一个细节把build.gradle里的AGP版本和Kotlin版本尽量统一并在README里写清楚JDK 11 Gradle 7.0.2的组合。不要以为大家都会默认新手很可能会去装最新JDK 21。4.4 一运行就报错还有哪些隐藏原因最后多说一句标题里一运行就报这个描述本身不一定就是刚才说的版本不匹配。有可能是因为自动导入了JDK 21导致Gradle无法解析也有可能只是项目缺少local.properties里的sdk.dir配置让Gradle找不到安卓SDK。这些报错有时跟版本不匹配的报错一同出现容易混淆。我的排查优先级一直是这样先看gradle-wrapper.properties里的版本再看gradle -v的实际JVM然后看build.gradle里的AGP版本最后看local.properties是否存在。按这个顺序走90%的一运行就报版本不匹配都能快速解决。5. 我的一点经验小结说真的版本不匹配这个问题本身不难难的是它总在你最着急的时候出现而且报错信息往往语焉不详。我处理过太多次类似情况最后总结出来的经验就是动手改之前一定先确认三个数字——Gradle版本号、JDK版本号、AGP版本号。这三者必须落在同一个兼容区间里不然你改这个、漏那个项目就会像一个三脚凳一样永远站不稳。最后分享一个我经常用的笨办法每次切换项目或换电脑我都会先在项目根目录跑一下./gradlew -v把输出的Gradle和JVM版本截图存下来。如果之后报错了直接从截图对比当前环境基本一眼就能看出是哪个版本出轨了。这个习惯帮我省了很多排查时间也推荐你用起来。

相关新闻

基于RAG与本地部署的情感智能助手:混合检索与重排序实战

基于RAG与本地部署的情感智能助手:混合检索与重排序实战

1. 为什么我要在本地折腾一个情感智能助手先说结论:我做这个项目的出发点特别朴素——我需要一个能理解情绪、能记住上下文、还能离线跑的对话助手,用来做情感陪伴类的产品原型验证。市面上现成的方案要么把数据传到云端让我不放心,要么检索效…

2026/10/18 14:07:13 阅读更多 →
PHP匿名聊天室源码全解析:从轮询长轮询到双端自适应

PHP匿名聊天室源码全解析:从轮询长轮询到双端自适应

简介:这是一份基于 PHP 语言开发的匿名在线聊天室系统源码,定位为可直接部署的轻量实时社交应用,适合希望学习 PHP 后端、前端交互与响应式页面结合的初中级开发者,也可用于快速搭建无需注册的互动交流社区。压缩包共 1843 个文件…

2026/10/17 20:04:06 阅读更多 →
C# Winform用户权限系统实战:从RBAC四表设计到按钮级拦截

C# Winform用户权限系统实战:从RBAC四表设计到按钮级拦截

简介:面向需要构建桌面端后台管理系统的.NET开发者,这一压缩包提供C#Winform与MySQL结合的完整用户管理功能实现,覆盖用户创建、角色创建、操作日志记录和基于角色的权限控制等核心业务场景。解决方案以WinformDemo为入口,共包含4…

2026/10/17 3:10:59 阅读更多 →

最新新闻

HTML/CSS智能补全:语义化编码与前端效率革命

HTML/CSS智能补全:语义化编码与前端效率革命

1. 这不是“快捷键教学”&#xff0c;而是前端效率革命的起点你有没有过这样的时刻&#xff1a;写HTML时&#xff0c;手在键盘上敲了十几遍<div class"container">&#xff0c;光是闭合标签就反复按了三次方向键&#xff1b;写CSS时&#xff0c;想加个margin: …

2026/10/18 14:07:20 阅读更多 →
WebView Cookie丢失与跨域登录态不同步:排查思路与修复实践

WebView Cookie丢失与跨域登录态不同步:排查思路与修复实践

做移动端开发这几年&#xff0c;WebView 里 Cookie 丢失是我踩过最频繁的坑之一。用户明明在原生页面登录成功&#xff0c;一跳到 H5 页面又打回原形&#xff1b;同一个域名下接口访问正常&#xff0c;换个域名就完全拿不到会话&#xff1b;甚至同一个 WebView 里前后两个页面&…

2026/10/18 14:07:20 阅读更多 →
Spring Boot社区助老志愿者服务平台:毕设架构与跑通指南

Spring Boot社区助老志愿者服务平台:毕设架构与跑通指南

简介&#xff1a;基于SpringBoot的社区助老志愿者服务平台毕业设计项目&#xff0c;面向计算机相关专业学生与需要快速搭建完整毕设方案的开发者。系统采用Java语言与SpringBoot框架&#xff0c;围绕志愿者服务、老人信息管理等核心功能展开&#xff0c;涵盖需求分析、系统结构…

2026/10/18 14:07:20 阅读更多 →
基于YOLOv8的安全帽与反光衣检测:数据、训练到部署全流程实战

基于YOLOv8的安全帽与反光衣检测:数据、训练到部署全流程实战

工地安全监管这事&#xff0c;我一直觉得是个典型的“看着简单、做好了很难”的落地场景。这两年YOLO系列模型迭代速度飞快&#xff0c;尤其是YOLOv8出来之后&#xff0c;做安全帽检测的方案在网上已经满天飞。但真要把“安全帽反光衣检测”做成一个拿得出手、能实际跑起来的项…

2026/10/18 14:07:20 阅读更多 →
基于YOLOv26的变电站变压器设备检测与智能巡检实践

基于YOLOv26的变电站变压器设备检测与智能巡检实践

在电力巡检这个圈子里摸爬滚打了几年&#xff0c;我越来越觉得&#xff0c;目标检测模型换了一代又一代&#xff0c;直到YOLOv26出来之后&#xff0c;才算真正把变电站变压器设备检测与识别这件事做得比较舒服。今天就跟大家聊聊&#xff0c;我是怎么基于YOLOv26做了一套完整的…

2026/10/18 14:07:20 阅读更多 →
ERP问卷集成总对不上字段?2026我试了五款谁对接更稳当些

ERP问卷集成总对不上字段?2026我试了五款谁对接更稳当些

[本文为个人项目选型实测记录&#xff0c;所有工具均自行注册体验&#xff0c;无任何厂商合作&#xff0c;内容仅作为技术选型参考。]背景上个月薪酬模块上线&#xff0c;HR要求把员工满意度问卷的部门和职级字段直接同步进ERP人事档案。结果头一批数据导进去&#xff0c;部门I…

2026/10/18 14:06:19 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →