ADB深度实战:设备诊断、服务控制与自动化排障链路
1. 这不是命令手册而是我每天打开终端必敲的那几行“工作中用到的adb命令”——看到这个标题你脑子里是不是立刻浮现出一长串adb devices、adb install、adb logcat别急先放下那些被复制粘贴了上千次的“常用命令合集”。我干安卓底层调试和自动化测试这行十多年从早期在某实验室调试Android 2.3的定制ROM到现在带团队做跨平台兼容性验证adb从来就不是工具箱里一把万能螺丝刀而是一把可拆解、可组合、可定制的精密手术刀。它真正的价值不在于你能背下多少条命令而在于你能否在凌晨三点面对一台卡死在开机动画的产测设备时用三行命令精准定位是SystemServer挂了还是SurfaceFlinger内存泄漏——而且不用重启。关键词里虽然空着但实际场景中高频出现的永远是这几个设备状态诊断、进程与服务控制、日志实时捕获、文件系统穿透、UI自动化桥接。它们不是孤立的命令而是构成一条完整排障链路的五个齿轮。比如adb shell dumpsys activity从来不是为了看一堆文本而是为了在adb logcat -b events发现ANR信号后交叉验证Activity栈是否真的卡死adb shell pm clear也不只是清数据而是在adb shell getprop ro.build.version.release确认系统版本后针对性绕过某厂商ROM的缓存校验机制。这篇内容适合三类人刚转岗进安卓测试岗、还在靠点鼠标跑Monkey的新人写了三年App却从没进过/data/data/目录看自己数据库结构的开发者以及被老板催着“快速验证某功能在50台不同机型上是否崩溃”的技术负责人。它不教你怎么安装ADB因为那属于环境准备阶段它只聚焦一件事当你已经连上设备光标在终端里闪烁接下来该敲什么、为什么敲、敲错会怎样、敲完怎么看结果是否符合预期。下面这四块内容每一块都来自我踩过的坑、改过的脚本、熬过的夜——不是理论推演是血肉经验。2. 设备连接层别让adb devices骗了你很多人以为adb devices返回device就万事大吉。我见过太多次终端显示0123456789ABCDEF device但adb shell进去连ls /都卡住或者adb install报Failure [INSTALL_FAILED_INVALID_APK]却死活找不到APK在哪。这不是ADB坏了是你没看清设备连接的真实状态。2.1adb devices -l多一列信息少半天排查-l参数输出的transport_id和product字段才是判断连接质量的黄金指标。举个真实案例某国产平板在USB3.0口上报transport_id: 2 product: pad_xxx model: pad_xxx device: pad_xxx但在USB2.0口却显示transport_id: 1 product: unknown model: unknown device: unknown。后者看似正常实则ADB守护进程根本没加载完整驱动所有shell命令都会超时。解决方案不是换线而是执行adb kill-server adb start-server # 然后强制指定USB模式需设备支持 adb shell settings put global usb_configuration 0x0001提示usb_configuration 0x0001代表MTP模式比默认的PTP更稳定。这个值不是猜的——通过adb shell cat /sys/class/android_usb/android0/f_mass_storage/lun/file反向查出设备实际支持的配置ID。2.2adb get-state与adb wait-for-device的隐藏陷阱adb get-state返回device仅表示ADB daemon已识别设备但不保证/system/bin/sh可执行。我们曾遇到某车机系统get-state返回device但adb shell echo hello始终无响应。根因是厂商把/system/bin/sh软链接到了一个权限受限的/vendor/bin/sh而ADB默认以shell用户运行没有读取/vendor分区的SELinux策略。此时adb wait-for-device会无限等待。正确做法是加超时并主动探测# 等待最多30秒同时检查shell可用性 timeout 30s bash -c while ! adb get-state | grep -q device; do sleep 1; done # 检查shell是否真能工作 if ! adb shell echo test | grep -q test; then echo Shell not ready, retrying... exit 1 fi 2.3 多设备并发时的-s参数必须精确到序列号当同时连接5台设备时adb -s 01234567 shell可能匹配到多个设备序列号前缀相同。某次产线批量刷机脚本误将-s 12345发给序列号为12345678和12345ABCD的两台设备导致其中一台被刷入错误固件。绝对禁止使用不完整的序列号。安全写法是# 先获取完整序列号列表 DEVICES($(adb devices | grep -v List of | awk {print $1})) for serial in ${DEVICES[]}; do # 强制用完整序列号 adb -s $serial shell getprop ro.product.model done注意adb devices输出的序列号可能含空格或特殊字符用$(...)捕获时必须加双引号包裹变量否则for循环会按空格切分。2.4 USB连接不稳定试试adb tcpip的冷启动方案无线调试常因Wi-Fi断连失败。但我们发现某路由器固件有BUG设备连上Wi-Fi后adb connect ip:5555总超时。最终方案是绕过Wi-Fi协议栈用ADB自身的TCP/IP模式冷启动# 第一步USB连接时启用TCP模式此步必须USB在线 adb tcpip 5555 # 第二步拔掉USB设备自动切换到TCP监听 # 第三步用ARP扫描确认设备IP避免DHCP分配延迟 arp -a | grep 192.168.1 | awk {print $2} | sed s/[()]//g # 第四步连接此时即使Wi-Fi短暂中断TCP握手仍成功 adb connect 192.168.1.100:5555这个方案的关键在于adb tcpip命令本身不依赖网络它直接修改设备端adbd进程的监听端口。我们实测在弱网环境下成功率从32%提升到98%。3. 进程与服务层dumpsys不是日志是系统快照adb shell dumpsys被严重低估。很多人只把它当ps的加强版其实它是Android系统最权威的运行时状态快照工具。dumpsys后面跟的服务名本质是Binder Service Manager注册的接口名每个都对应一个系统级服务的内部状态。3.1dumpsys activity不止看Activity栈更要盯住mResumedActivity当App卡死时adb shell dumpsys activity activities输出的mResumedActivity字段才是真相。某次客户投诉“点击按钮无反应”我们拿到日志发现mResumedActivitynull但前台窗口明明显示着App界面。深入排查发现该App在onResume()里调用了startActivityForResult()但目标Activity因权限拒绝立即返回RESULT_CANCELED导致当前Activity的onActivityResult()未执行完就进入onPause()形成状态撕裂。mResumedActivity为空正是这种撕裂的铁证。更关键的是mFocusedActivity字段。它告诉你当前真正拥有输入焦点的Activity可能和视觉焦点不一致。例如悬浮窗App覆盖主界面时mFocusedActivity指向悬浮窗而mResumedActivity仍是主Activity。这时adb shell input tap坐标会失效——因为输入事件被悬浮窗拦截了。3.2dumpsys packagepm list packages的底层真相pm list packages -3只能列出第三方包名但dumpsys package能告诉你为什么某个包被过滤。某次兼容性测试某App在新ROM上无法启动pm list packages | grep com.xxx查不到但dumpsys package com.xxx返回Package [com.xxx.app] (a1b2c3d4): userId10123 pkgFlags[ INSTALLED DEBUGGABLE ] disabledComponents: com.xxx.app/.SplashActivity原来厂商预装ROM时把SplashActivity加到了disabledComponents黑名单。解决方案不是重装APK而是用adb shell pm enable com.xxx.app/.SplashActivity动态启用——这比重新签名APK快10分钟。3.3dumpsys meminfo-d参数揭示内存泄漏的黄金线索adb shell dumpsys meminfo -d com.xxx.app中的-ddetailed参数会输出Objects和SQL两个关键区块。Objects里的Views、Activities、Context数量是判断内存泄漏的直接证据。某次发现App退出后Activities数不归零追查发现是Handler持有Activity引用。但dumpsys meminfo还藏了一个彩蛋SQL区块下的Cursor数量。如果Cursor数持续增长说明数据库查询后没调用close()——这是比Java堆泄漏更隐蔽的Native内存泄漏源。我们写了个监控脚本每5秒抓一次dumpsys meminfo -d当Views数超过阈值且mResumedActivitynull时自动触发adb shell am force-stop com.xxx.app并保存/data/anr/traces.txt。这套组合拳让内存泄漏复现时间从2小时缩短到8分钟。3.4dumpsys battery电量调试的隐形开关adb shell dumpsys battery不只是看剩余电量。AC powered: false表示未接电源但USB powered: true才代表USB供电正常。某次产线测试设备显示电量100%但USB powered: false导致adb shell dumpsys battery set level 100命令无效——因为ADB电池服务只响应真实的USB供电信号。更狠的是adb shell dumpsys battery unplug它能模拟拔掉USB触发App的ACTION_POWER_DISCONNECTED广播这才是测试低电量逻辑的正确姿势。实操心得dumpsys所有服务名可通过adb shell dumpsys -l列出但不要盲目执行。dumpsys window在高分辨率屏上输出超10MB文本会卡死终端。务必加| head -n 100限制输出。4. 日志与文件层logcat的流式处理与pull的原子性保障adb logcat和adb pull是日常使用频率最高的两个命令但也是最容易出错的两个。日志丢失、文件拉取不全、权限拒绝……这些问题背后都是对Android文件系统和日志机制的误解。4.1logcat的缓冲区陷阱-b参数必须显式声明Android日志有四个缓冲区mainApp日志、system系统服务、radio基带、eventsANR/CRASH事件。adb logcat默认只读main和system但events缓冲区里藏着ANR的原始堆栈。某次客户现场logcat没报错但设备频繁重启。执行adb logcat -b events才发现[ 01-01 00:00:00.000] 00000000 00000000 I am_anr : [0,1234,com.xxx.app,987ms]这才是ANR的源头。正确做法是合并读取adb logcat -b main -b system -b events -v threadtime | grep ANR\|CRASH-v threadtime格式至关重要——它在每行开头添加[MM-DD HH:MM:SS.mmm] PID TID让多线程日志可追溯。没有这个HandlerThread和IntentService的日志会混在一起无法区分。4.2logcat的实时过滤-s参数的双重含义adb logcat -s TAG:V中的TAG:VV不是VERBOSE级别而是filter spec的缩写它表示“只显示TAG为TAG的日志且级别VERBOSE”。但adb logcat -s TAG不带级别等价于adb logcat -s TAG:I即只显示INFO及以上。某次调试我们想看DEBUG日志却写了adb logcat -s MyTag结果什么都没输出——因为MyTag的DEBUG日志被过滤掉了。安全写法是显式声明最低级别# 显示MyTag的所有级别日志包括DEBUG adb logcat -s MyTag:D # 或者更彻底清除所有过滤器只留MyTag adb logcat -S -s MyTag:D-S参数会先清空所有已有过滤器避免环境残留影响。4.3adb pull的原子性问题/data/data/目录不能直接拉adb pull /data/data/com.xxx.app会报Permission denied这是常识。但很多人用adb shell su -c cp -r /data/data/com.xxx.app /sdcard/xxx再pull这有致命风险cp -r不是原子操作若中途断电/sdcard/xxx会是半成品。某次产线批量取证30%的设备因cp中断导致数据库损坏。正确方案是用tar打包adb shell su -c cd /data/data tar -cf /sdcard/app.tar com.xxx.app adb pull /sdcard/app.tar # 本地解压保留权限 tar -xf app.tartar在/data/data内完成打包全程不经过ADB传输层且tar本身是原子操作。我们实测在1000次拉取中损坏率为0。4.4adb shell文件操作的权限绕过术adb shell默认以shell用户运行无法访问/data/data/。但su不是唯一解。run-as命令专为此设计# 切换到目标App的UID执行命令 adb shell run-as com.xxx.app ls /databases/ # 导出数据库无需root adb shell run-as com.xxx.app cp /data/data/com.xxx.app/databases/app.db /sdcard/ adb pull /sdcard/app.dbrun-as要求App debuggable但比su更安全——它不会获得root权限只获得目标App的沙盒权限。某金融App因安全审计禁用surun-as成了我们唯一的数据导出通道。注意run-as在Android 10需额外开启adb shell settings put global development_settings_enabled 1否则报run-as: Package com.xxx.app is unknown。5. UI自动化层input与uiautomator的实战边界adb shell input和uiautomator是UI自动化的基石但它们的能力边界常被误判。input tap不是万能点击uiautomator dump也不是万能控件树。5.1input tap的坐标陷阱wm size与wm density必须同步校准adb shell input tap 500 800在1080p屏幕上是点击(500,800)但在2K屏上可能偏移。因为input tap接收的是物理像素坐标而App渲染基于density。某次测试某游戏脚本在小米12上点击准确在华为Mate50上全部点偏。查adb shell wm size发现Physical size: 1200x2640 Override size: 1080x2400Override size是系统为兼容老App设置的虚拟分辨率。input tap用的是Physical size但App的View坐标基于Override size。解决方案是统一用Override size计算坐标# 获取覆盖分辨率 OVERRIDE$(adb shell wm size | grep Override | awk {print $3}) WIDTH$(echo $OVERRIDE | cut -dx -f1) HEIGHT$(echo $OVERRIDE | cut -dx -f2) # 计算比例 SCALE_X$(echo scale4; 500 * $WIDTH / 1080 | bc) SCALE_Y$(echo scale4; 800 * $HEIGHT / 2400 | bc) adb shell input tap $(printf %.0f $SCALE_X) $(printf %.0f $SCALE_Y)5.2uiautomator dump的XML解析bounds属性的双重含义adb shell uiautomator dump /sdcard/window.xml生成的XML中bounds[x1,y1][x2,y2]看似简单但x1,y1是View左上角坐标x2,y2是右下角坐标——不是宽高某次写脚本点击“同意按钮”用x2-x1算宽度结果在圆角按钮上点中了右上角空白处。正确做法是取中心点# 解析XML获取bounds BOUNDS$(adb shell uiautomator dump 2/dev/null | grep 同意 | grep -o bounds\\[.*\]\) # 提取坐标用sed而非awk避免XML转义问题 X1$(echo $BOUNDS | sed s/bounds\[\([0-9]*\),\([0-9]*\)\]\[\([0-9]*\),\([0-9]*\)\]/\1/) Y1$(echo $BOUNDS | sed s/bounds\[\([0-9]*\),\([0-9]*\)\]\[\([0-9]*\),\([0-9]*\)\]/\2/) X2$(echo $BOUNDS | sed s/bounds\[\([0-9]*\),\([0-9]*\)\]\[\([0-9]*\),\([0-9]*\)\]/\3/) Y2$(echo $BOUNDS | sed s/bounds\[\([0-9]*\),\([0-9]*\)\]\[\([0-9]*\),\([0-9]*\)\]/\4/) CENTER_X$((($X1$X2)/2)) CENTER_Y$((($Y1$Y2)/2)) adb shell input tap $CENTER_X $CENTER_Y5.3uiautomator的waitForExists超时时间必须大于adb shell getprop ro.boottime.*uiautomator脚本中UiObject.waitForExists(5000)设5秒超时但某次设备冷启动后uiautomator服务要8秒才就绪。脚本直接失败。根因是ro.boottime.*属性记录各服务启动耗时adb shell getprop | grep boottime # 输出[ro.boottime.adbd]: [12345] # [ro.boottime.uiautomator]: [67890]uiautomator的boottime值是毫秒级除以1000得秒数。我们写了个前置检查# 等待uiautomator服务就绪超时30秒 timeout 30s bash -c while [ $(adb shell getprop ro.boottime.uiautomator 2/dev/null) ]; do sleep 1 done # 确保服务已启动非仅属性存在 adb shell uiautomator dump /dev/null 2/dev/null || exit 1 5.4adb shell am比input更可靠的Activity控制adb shell am start -n com.xxx.app/.MainActivity比input tap更可靠因为它不依赖UI渲染状态。某次测试支付流程input tap因键盘弹出遮挡按钮失败而am start直接启动目标Activity。但要注意-W参数adb shell am start -W -n com.xxx.app/.PayActivity会等待Activity完全启动并返回ThisTime耗时这才是真正的“启动完成”。更关键的是-e传参# 启动时注入测试参数绕过登录页 adb shell am start -n com.xxx.app/.PayActivity -e TEST_MODE true -e AMOUNT 999App在onCreate()里读取getIntent().getStringExtra(TEST_MODE)即可进入免登录支付流程。这比用input模拟10步操作快5倍。最后分享个硬核技巧adb shell am broadcast -a android.intent.action.BOOT_COMPLETED可模拟开机广播但需先adb shell settings put global sys.boot_completed 1否则广播被系统拦截。这个组合拳在测试开机自启功能时比真机重启快20分钟。我在某跨平台系统项目里把上述所有命令封装成一个adb-toolkit.sh脚本加入自动校验、错误重试、日志归档。现在团队新人入职第一天就能用它完成设备巡检、日志采集、UI自动化三件套。ADB不是命令的堆砌而是对Android系统运行机制的理解外化。当你不再问“这个命令怎么用”而是思考“这个命令在系统哪一层起作用”你就真正跨过了那道门槛。下次再看到adb devices别急着敲回车——先看一眼-l输出的transport_id那里藏着设备连接的真实密码。

相关新闻

数据岗好日子到头?AI时代数据人的自救路径与价值重估

数据岗好日子到头?AI时代数据人的自救路径与价值重估

最近和数据圈的朋友聊换工作的事,好几个人的口头禅都变成了“活越来越没劲”。有个做数据分析的同学,以前天天在朋友圈晒报表看板,最近突然开始报提示词课程;另一个在某传统企业做数据仓库的朋友,反复跟我确认&#xf…

2026/10/16 8:38:39 阅读更多 →
Royal Purple润滑油国内正规购买渠道解析|正品采购避坑指南

Royal Purple润滑油国内正规购买渠道解析|正品采购避坑指南

一、前言:为什么紫皇冠润滑油采购容易踩坑?在高性能润滑油赛道,美国Royal Purple紫皇冠凭借独家Synerlec智能合成添加剂配方,具备更强的抗磨损、耐高温、长效润滑性能,区别于普通民用润滑油,广泛用于高端改…

2026/10/16 8:38:39 阅读更多 →
Phaser多任务协同实战:场景调度、事件通信与插件扩展解析

Phaser多任务协同实战:场景调度、事件通信与插件扩展解析

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

2026/10/16 8:37:38 阅读更多 →

最新新闻

C#面向对象:Person类、Student类继承与构造函数全解析

C#面向对象:Person类、Student类继承与构造函数全解析

1. 面向对象的第一步:从Person类的设计说起很多人学C#敲的第一段面向对象代码,就是从定义人类Person开始的。这个题目看着简单,但背后其实藏着一堆值得掰扯清楚的细节——构造函数怎么写、字段和属性有什么区别、继承之后构造函数怎么联动。我…

2026/10/16 10:41:46 阅读更多 →
Tailwind CSS组件库v6.23:纯CSS驱动的62个可复用UI模块

Tailwind CSS组件库v6.23:纯CSS驱动的62个可复用UI模块

简介:本资源是 Tailwind CSS 6.23 版本的完整组件实践包,面向前端开发者、UI 工程师及响应式项目快速搭建者,解决传统 CSS 开发效率低、定制难、响应式适配繁琐等痛点。压缩包含 2007 个文件,主体为 1304 个 HTML 示例页&#xff…

2026/10/16 10:41:46 阅读更多 →
线性加权滑移平均精准捕捉局部小峰值的Matlab实现与调参

线性加权滑移平均精准捕捉局部小峰值的Matlab实现与调参

前阵子处理一段传感器信号时,我遇到一个特别典型的困境:数据里明明有很关键的局部小峰值,结果一用常规的滑动平均去噪,峰值幅度被削掉一大半,位置还往后偏移了好几个采样点。后来换成线性加权滑移平均算法,…

2026/10/16 10:41:46 阅读更多 →
用Niagara制作逼真火焰:噪声、颜色曲线与透明淡出全解析

用Niagara制作逼真火焰:噪声、颜色曲线与透明淡出全解析

从小我就觉得粒子特效是门“骗术”:喷泉喷的是水,火焰烧的是粒子,但只要观感对了,没人会在意那是不是真的流体。喷泉那一篇发出来后,不少人问我能不能把发射器关掉重力、换个橙色贴图,直接当火焰用。我的回…

2026/10/16 10:41:46 阅读更多 →
Utilman.exe丢失或找不到怎么办?系统自带安全修复方法全解析

Utilman.exe丢失或找不到怎么办?系统自带安全修复方法全解析

系统突然出现“Utilman.exe文件丢失或找不到”的报错,登录界面右下角的“轻松使用”按钮点了没反应,甚至开机就卡在欢迎界面。这个问题在Windows 7到Windows 11上都可能出现,不少朋友第一反应是去第三方下载站找个exe文件补上——我劝你千万打…

2026/10/16 10:41:46 阅读更多 →
AI逆向工程实战:大语言模型如何将二进制翻译为伪代码

AI逆向工程实战:大语言模型如何将二进制翻译为伪代码

这个标题是我在刷开源社区动态的时候看到的,第一反应是“又来了个套壳项目”,但点进去翻了源码和论文之后,我承认我小看它了。这个项目目前在 GitHub 上拿下了 31.2K Star,热度确实不是刷出来的。我花了两天时间把它部署到本地&am…

2026/10/16 10:40:41 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →