Android图书阅读器源码解析:从MVC分层到TXT导入与自动书签实现
简介这份PDF文献面向Android客户端开发学习者与毕业设计选题者系统讲解了一款图书阅读器APP从需求分析到编码落地的完整实现路径可作为应用开发方向的参考文献与专业指导。资源包内仅含1个PDF文件大小约1.4MB内容以论文形式呈现涵盖系统总体功能结构图、客户端与服务端设计思路及关键模块说明。文中将系统划分为Android客户端、服务端与后台管理三大模块客户端基于Java与Android Studio开发采用MVC框架模型层负责业务逻辑与数据库读写视图层用XML布局描述界面控制层由Activity实现服务端以Tomcat搭建、MySQL管理数据。功能层面覆盖游客浏览搜索、注册用户在线阅读与下载、管理员上传审核等角色分工并细化到用户注册登录、我的书架、护眼模式、本地TXT阅读、书签自动记录等实现要点。目前已有178人学习适合需要参考完整项目结构与模块划分的开发者研读。1. 从一份 2018 年的课程设计说起这套 Android 图书阅读器源码到底能跑出什么翻到这份《基于 Android Studio 平台的图书阅读器的设计与实现》第一反应不是又一个课程设计而是它把移动端阅读类 App 的完整链路走通了——Android 客户端、Tomcat 服务端、MySQL 数据库、后台管理四块拼在一起不是只画了个界面就交差。作者是无锡商业职业技术学院的胡剑锋发表在《电脑知识与技术》2018 年第 36 期全文只有两页但功能结构图、模块划分、文件组织都列得清清楚楚。这套东西适合谁如果你正在做 Android 课程设计、毕业设计或者想找一个麻雀虽小五脏俱全的客户端服务端练手项目它比那些只有 UI 没有后端的 Demo 强得多。游客能浏览搜索注册用户能在线阅读、下载 TXT、管理书架管理员能审核用户、上架电子书、看阅读排行榜——三类角色的权限边界是明确的。下面我按资源是什么 → 怎么用 → 坑在哪的顺序把这份 PDF 里的设计拆成能照着复现的步骤。2. 客户端 MVC 分层与文件组织把 Activity、Fragment、res 三块摆正2.1 为什么 2018 年的项目还在用 MVC 而不是 MVVM原文明确写了客户端采用 MVC 框架模型层管业务逻辑、数据库读写、网络访问视图层用 layout 下的 XML 布局文件描述界面控制层通过 Activity 实现。放到今天看MVC 在 Android 上确实有硬伤——Activity 既当 Controller 又容易和 View 纠缠一个页面逻辑一多就变成上帝类。但这份项目的场景是课程设计级别页面数量有限MVC 的分层反而比 MVVM 更容易讲清楚数据从哪来、界面怎么渲染。我一般会这样判断如果项目里 Activity 不超过 10 个、没有复杂的双向数据绑定需求MVC 够用且上手快一旦页面超过 15 个、开始出现跨页面状态共享就该考虑 MVP 或 MVVM 了。这份项目属于前者所以它的分层是合理的不是偷懒。2.2 App 文件组织结构逐层拆解原文把文件组织分成三块App 文件 Manifest、Java 文件主要是 Activity、res 资源文件夹。这个划分对应到实际工程里就是app/src/main/ ├── AndroidManifest.xml # 四大组件注册、权限声明 ├── java/com/example/reader/ │ ├── MainActivity.java # 首界面承载精选/分类/用户四个 Fragment │ ├── HeadFragment.java # 图书介绍 离线下载 在线观看 │ ├── GoodFragment.java # 图书分类 界面设计 │ ├── MorebooksFragment.java # 分类图书介绍 右滑功能 │ └── MyFragment.java # 登录注册 我的书架 护眼模式 └── res/ ├── drawable/ # 各页面图片资源 ├── layout/ # 各页面 XML 布局 ├── mipmap/ # 应用图标 └── values/ # 颜色、字符串配置逻辑说明MainActivity 用 Fragment 做底部导航的容器四个 Fragment 分别对应精选、分类、书架、我的四个 Tab。HeadFragment 承担图书详情页的职责GoodFragment 和 MorebooksFragment 负责分类浏览MyFragment 把用户体系和书架、护眼模式收在一起。参数说明AndroidManifest.xml里必须声明INTERNET权限网络请求、READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE本地 TXT 导入导出、CAMERA注册时拍照上传头像。漏掉存储权限本地电子书导入会直接崩这是最常见的翻车点。2.3 用户模块的登录态保持与验证码逻辑原文写得很具体登录成功后用 Android 自带的SharedPreferences保存用户名密码再次进入只需输入验证码即可登录。注册时头像支持选择本地照片和拍照两种方式个人信息修改后以 JSON 上传服务器。// 登录成功后保存凭证 SharedPreferences sp getSharedPreferences(user_session, MODE_PRIVATE); SharedPreferences.Editor editor sp.edit(); editor.putString(username, username); editor.putString(password, password); // 实际项目建议存 token不要存明文密码 editor.putBoolean(is_login, true); editor.apply(); // 再次进入时读取 boolean isLogin sp.getBoolean(is_login, false); if (isLogin) { // 只需展示验证码输入框跳过账号密码 }逻辑说明SharedPreferences是 Android 轻量级键值存储适合存登录态这种小数据。原文的做法是存用户名密码这在课程设计里能跑通但生产环境必须换成 token 机制——密码明文落盘是安全红线。参数说明MODE_PRIVATE表示只有当前应用可读这是唯一该用的模式。apply()是异步写入commit()是同步写入登录场景用apply()即可不会阻塞主线程。3. 电子书阅读模块在线阅读、本地 TXT 导入与书签自动生成3.1 在线阅读的数据流与书签机制原文描述进入首页选择图书类型查询数据库获取图书信息和封面点击免费阅读进入阅读界面。关键细节是——用户离开阅读界面时系统自动生成书签再次阅读时自动跳转到上次结束位置。这个自动书签的实现思路通常是在onPause()或onStop()生命周期回调里记录当前滚动位置或页码写入本地数据库或SharedPreferences。Override protected void onPause() { super.onPause(); // 记录当前阅读位置 int currentPosition readingView.getScrollY(); // 或当前页码 SharedPreferences sp getSharedPreferences(bookmark, MODE_PRIVATE); sp.edit().putInt(book_ bookId, currentPosition).apply(); } Override protected void onResume() { super.onResume(); // 恢复上次阅读位置 SharedPreferences sp getSharedPreferences(bookmark, MODE_PRIVATE); int lastPosition sp.getInt(book_ bookId, 0); readingView.scrollTo(0, lastPosition); }逻辑说明onPause()在页面失去焦点时触发是保存阅读进度的最佳时机。用bookId作为 key 后缀保证每本书独立记录进度。onResume()在页面重新获得焦点时恢复位置。参数说明getScrollY()返回的是垂直滚动偏移量适合纯文本滚动阅读器如果用的是ViewPager分页阅读应该记录页码而非滚动量。默认值传 0表示没有历史记录时从头开始。3.2 本地 TXT 导入与书架管理原文明确目前仅支持本地 TXT 文档的电子书阅读。用户将已下载的电子书导入 App添加至我的书架点击即可阅读。下载的电子书也以 TXT 格式存放在本地手机。// 从本地文件选择器导入 TXT Intent intent new Intent(Intent.ACTION_GET_CONTENT); intent.setType(text/plain); startActivityForResult(intent, REQUEST_CODE_PICK_TXT); // 在 onActivityResult 中处理 Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode REQUEST_CODE_PICK_TXT resultCode RESULT_OK) { Uri uri data.getData(); // 读取 TXT 内容 try (InputStream is getContentResolver().openInputStream(uri); BufferedReader reader new BufferedReader(new InputStreamReader(is, UTF-8))) { StringBuilder sb new StringBuilder(); String line; while ((line reader.readLine()) ! null) { sb.append(line).append(\n); } String content sb.toString(); // 存入书架数据库 saveToBookshelf(uri.toString(), content); } catch (IOException e) { e.printStackTrace(); } } }逻辑说明ACTION_GET_CONTENT拉起系统文件选择器setType(text/plain)过滤只显示 TXT 文件。通过ContentResolver打开输入流读取内容注意指定 UTF-8 编码——中文 TXT 如果是 GBK 编码会乱码这是血泪经验。参数说明REQUEST_CODE_PICK_TXT是自定义请求码用于在onActivityResult中区分不同来源的返回。saveToBookshelf需要自己实现通常是把文件路径和内容摘要写入 SQLite。3.3 搜索功能的模糊匹配与 JSON 返回原文写用户输入电子书名称、作者或主角关键词系统后台模糊匹配结果以 JSON 格式返回客户端客户端解析后以列表展示。-- 服务端模糊搜索 SQL SELECT id, title, author, cover_url, category FROM books WHERE title LIKE CONCAT(%, ?, %) OR author LIKE CONCAT(%, ?, %) OR protagonist LIKE CONCAT(%, ?, %) ORDER BY click_count DESC LIMIT 20;逻辑说明LIKE CONCAT(%, ?, %)是 MySQL 中实现模糊匹配的标准写法?是预编译占位符防止 SQL 注入。ORDER BY click_count DESC让热门书排在前面和原文提到的点击率排行榜呼应。参数说明LIMIT 20限制返回条数避免一次拉取过多数据导致客户端卡顿。如果数据量大应该加分页参数LIMIT offset, size。4. 服务端与后台管理Tomcat MySQL 的角色权限与排行榜统计4.1 三类角色的权限边界怎么落地原文把角色分成游客、注册用户、管理员。游客只能浏览和搜索注册用户增加阅读、下载、书架管理员负责图书上传、用户审核。这个权限模型在服务端通常用一张user表的role字段区分。角色role 值可访问接口游客0未登录图书列表、搜索、图书详情注册用户1上述 下载、书架增删、个人信息修改分类管理员2上述 本分类图书审核上架超级管理员3全部 分类管理员账户管理逻辑说明接口层用拦截器或过滤器校验role值低于接口要求的角色直接返回 403。原文提到分类管理员账户由超级管理员添加生成只负责该分类电子书的审核上架所以还需要一张admin_category关联表记录每个管理员负责哪些分类。参数说明role用整型而非字符串查询效率更高也方便做范围判断如role 2表示管理员级别。4.2 阅读排行榜与用户喜好推荐的数据来源原文提到两个统计电子书点击率和阅读量形成排行榜热度前十在首页推荐用户在线次数和时长形成喜好据此推荐书籍。-- 阅读排行榜 SELECT b.id, b.title, b.author, COUNT(r.id) AS read_count FROM books b LEFT JOIN reading_log r ON b.id r.book_id WHERE r.created_at DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY b.id ORDER BY read_count DESC LIMIT 10; -- 用户喜好统计某用户阅读最多的分类 SELECT b.category, COUNT(*) AS cnt FROM reading_log r JOIN books b ON r.book_id b.id WHERE r.user_id ? GROUP BY b.category ORDER BY cnt DESC LIMIT 3;逻辑说明排行榜按最近 7 天的阅读记录统计避免老数据长期霸榜。用户喜好取阅读量前三的分类用于推荐同分类新书。参数说明DATE_SUB(NOW(), INTERVAL 7 DAY)计算 7 天前的时间点是 MySQL 日期运算的常用写法。LEFT JOIN保证没有阅读记录的书也出现在结果里read_count 为 0但排行榜场景通常用INNER JOIN过滤掉零阅读的书更合理。4.3 服务端环境搭建的关键配置原文写服务器端用 Eclipse 开发、Tomcat 搭建、MySQL 管理数据库。这套组合在 2018 年是主流现在复现需要注意版本兼容。# Tomcat 部署 Web 项目 # 1. 将编译好的 war 包放入 webapps 目录 cp reader-server.war $TOMCAT_HOME/webapps/ # 2. 启动 Tomcat $TOMCAT_HOME/bin/startup.sh # 3. 确认 MySQL 连接配置 # 在项目的 db.properties 中配置 # jdbc.urljdbc:mysql://localhost:3306/reader_db?useUnicodetruecharacterEncodingUTF-8 # jdbc.usernameroot # jdbc.passwordyour_password逻辑说明war 包放入webapps后 Tomcat 会自动解压部署。数据库连接串必须带useUnicodetruecharacterEncodingUTF-8否则中文书名和作者名会乱码。参数说明Tomcat 8.5 搭配 JDK 8 是这套项目的稳定组合MySQL 5.7 比 8.0 更省心因为 8.0 默认的caching_sha2_password认证插件会让老版本 JDBC 驱动连不上需要额外配置。5. 避坑与排查这套 2018 年的项目在当下复现会撞上什么5.1 现象Android Studio 打开项目后 Gradle 同步失败原因原文项目基于 2018 年的 Gradle 版本大概率 4.x而你现在装的 Android Studio 可能自带 Gradle 7.x 或 8.x版本跨度太大导致插件不兼容。解决不要直接改 Gradle 版本硬升先看build.gradle里的com.android.tools.build:gradle版本号去官网查它对应的 Gradle 版本然后在gradle-wrapper.properties里把distributionUrl改成匹配的版本。如果依赖库用的是compile而非implementation也要一并替换新版本 Gradle 已移除compile。5.2 现象本地 TXT 导入后中文显示为乱码原因TXT 文件编码不是 UTF-8可能是 GBK 或 GB2312而代码里用 UTF-8 读取。解决读取时先探测编码常见做法是用juniversalchardet库检测文件编码或者简单粗暴地先按 UTF-8 读如果出现乱码字符再回退到 GBK 重读。我一般会在导入时给用户一个编码选择下拉框让用户自己选比自动探测更可靠。5.3 现象真机运行时网络请求全部失败原因Android 9.0API 28之后默认禁止明文 HTTP 请求而这份 2018 年的项目服务端大概率是http://而非https://。解决在AndroidManifest.xml的application标签加android:usesCleartextTraffictrue或者配置network_security_config.xml只对特定域名放行。前者简单但全局放开后者更规范。5.4 现象SharedPreferences 保存的登录态在卸载重装后丢失原因SharedPreferences存在应用私有目录卸载时会被系统清除这是正常行为。解决如果需求是换设备也能保持登录必须把登录态存到服务端客户端只存 token每次启动用 token 换用户信息。原文的方案只适合同一设备内免重复登录的场景不要混淆。5.5 现象Tomcat 启动后访问接口返回 404原因war 包解压后的上下文路径和客户端请求的 URL 不一致。比如 war 包名叫reader-server.war访问路径应该是http://ip:8080/reader-server/接口名而不是http://ip:8080/接口名。解决要么改 war 包名为ROOT.war部署后路径就是根路径要么在客户端把 baseUrl 配成带上下文路径的完整地址。我一般会在客户端用一个Constants.BASE_URL统一管理改一处就行。6. 从 TXT 到多格式阅读器格式兼容的扩展思路与验证方法原文在结束语里自己承认了不足没有涉及电子书的多种格式对格式多样化的局面未充分考虑。这其实是这份项目最值得往下挖的地方——TXT 阅读器的核心逻辑是读文本、渲染文本、记录位置换成 EPUB 或 PDF变的只是解析层阅读器的骨架不用动。以 EPUB 为例它本质是一个 ZIP 包里面是 XHTML CSS 资源文件。扩展思路是在导入环节判断文件后缀TXT 走原有逻辑EPUB 走解压 解析 OPF 清单 按章节渲染 WebView 的路径。书架数据库加一个format字段区分类型阅读进度记录从滚动偏移量改成章节索引 章节内偏移。// 根据格式分发解析逻辑 public void openBook(String filePath) { String format filePath.substring(filePath.lastIndexOf(.) 1).toLowerCase(); switch (format) { case txt: parseTxt(filePath); break; case epub: parseEpub(filePath); // 解压 解析 OPF WebView 渲染 break; default: Toast.makeText(this, 暂不支持该格式, Toast.LENGTH_SHORT).show(); } }逻辑说明用文件后缀做分发是最简单的策略但不够严谨——有些 TXT 文件没有后缀。更稳妥的做法是读文件头魔数EPUB 是 ZIP 格式前两字节是PKTXT 没有固定魔数只能靠内容判断。课程设计级别用后缀判断就够了生产环境建议加魔数校验。参数说明toLowerCase()防止用户文件后缀大写导致匹配失败。parseEpub需要引入 EPUB 解析库常见的是epublib但它的 Android 兼容性需要自己验证。验证方法上我习惯用三个维度检查阅读器是否合格一是打开一本 5MB 以上的 TXT滚动是否流畅不卡顿二是阅读到一半杀进程再打开进度是否准确恢复三是导入一个 GBK 编码的 TXT中文是否正常显示。这三条过了基本功能就稳了。从那以后我每次拿到这种课程设计级的项目都强制先跑一遍编码 权限 网络明文三件套检查再谈功能扩展。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Java 8 Lambda 与 Stream 实战:从语法细节到集合处理重构

Java 8 Lambda 与 Stream 实战:从语法细节到集合处理重构

1. 为什么 Lambda 和 Stream 值得认真用一次1.1 先看一组对比:传统写法 vs Lambda/StreamJava 8 发布已经超过十年,Lambda 和 Stream 早就不是新鲜东西了。但我这几年做代码评审,发现很多团队的老代码里还在用十年前那种写法:明明…

2026/10/12 5:11:01 阅读更多 →
街机小游戏网页源码解析:从贪吃蛇到俄罗斯方块的实现技巧

街机小游戏网页源码解析:从贪吃蛇到俄罗斯方块的实现技巧

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

2026/10/12 5:11:01 阅读更多 →
SQL Server数据库修复实战:DBCC CHECKDB检查与数据抢救指南

SQL Server数据库修复实战:DBCC CHECKDB检查与数据抢救指南

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

2026/10/12 5:11:01 阅读更多 →

最新新闻

Python成绩统计作业复盘:从平行列表到字典与函数重构

Python成绩统计作业复盘:从平行列表到字典与函数重构

第二次作业发下来的那天,课程群里比平时安静了不少。第一次作业只要照着课堂示例把代码拼一拼,第二次题目一出,大家才发现要面对的是一整套流程:录入、存储、计算、排序、统计、输出。这道成绩统计题几乎在每个Python入门课程里都…

2026/10/12 5:52:28 阅读更多 →
前缀和进阶:哈希表、二维前缀和与树状数组

前缀和进阶:哈希表、二维前缀和与树状数组

刷LeetCode刷到一定量之后,你会发现前缀和就像一把“万能钥匙”:它能把区间求和从O(n)压到O(1),也能配合哈希表把子数组统计问题从O(n)压到O(n)。在上一个专题里,我详细讲过最基础的一维前缀和构造、区域和检索、中心下标这类直接…

2026/10/12 5:52:28 阅读更多 →
SpringBoot智能推荐卫生健康系统毕设实战:内容推荐算法实现

SpringBoot智能推荐卫生健康系统毕设实战:内容推荐算法实现

1. 项目概述1.1 这个毕设到底在做什么"基于springboot智能推荐的卫生健康系统的设计与实现",说人话就是:做一个能根据用户的身体状况、生活习惯和健康目标,主动给出个性化健康建议的Web平台。它不是一个简单的健康资讯网站&#xf…

2026/10/12 5:52:28 阅读更多 →
JAVA_HOME环境变量配置与排查:从报错到避坑全攻略

JAVA_HOME环境变量配置与排查:从报错到避坑全攻略

做了这么多年Java开发,几乎每个季度都得处理一次“JAVA_HOME环境变量”的幺蛾子。新同事入职第一件事是配JDK,老同事换项目第一件事是切版本,可翻来覆去出问题的,还是那个看起来人畜无害的JAVA_HOME。你可能也见过这样的报错&…

2026/10/12 5:52:28 阅读更多 →
3关键字B+树构建全解析:从分裂上提到删除合并

3关键字B+树构建全解析:从分裂上提到删除合并

如果你能在纸上从零构建一棵最多只装 3 个关键字的 B 树,那基本上就掌握了 B 树八成以上的难点。这是我当年准备面试时一个学长告诉我的,我照做之后发现确实如此——复杂的 m 阶 B 树,无非是把这里的“3”换成“几百”,分裂、上提…

2026/10/12 5:52:28 阅读更多 →
大模型推理优化实践:从KV Cache到语义缓存的三层缓存架构

大模型推理优化实践:从KV Cache到语义缓存的三层缓存架构

上个月排一个线上问题,我们的对外AI问答服务上线第三周,GPU没有扩容,但模型调用账单涨了快三倍。查了一圈下来最扎眼的还不是成本:平均每天十几万请求里差不多一半是“语义重复”——“附近有什么川菜馆”“川菜馆哪家好”“推荐一…

2026/10/12 5:51:27 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 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/11 10:45:37 阅读更多 →
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/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练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/11 14:36:54 阅读更多 →