Android进程优先级机制详解:从oom_score_adj到lmkd回收

做Android开发的这些年,进程优先级是我和新同事交流时最常被误解的一个概念。很多同学以为进程被杀是“系统心情不好”,其实是Android在内存吃紧时按规则做的取舍。只要理解了进程优先级,你不仅能把应用做得更稳,还能在线上出现“进程被回收”问题时快速定位原因。

1. 为什么Android要搞一套进程优先级

1.1 内存有限,系统必须在关键时候做取舍

Android手机的内存不像PC那么宽裕,即便是现在12GB、16GB的旗舰机,系统里跑的应用数量也多得远超想象。加上Android后台默认不清理应用,大部分应用都留下了活跃或半活跃的进程。如果一个应用占着内存不肯释放,而另一个应用又打算启动,系统就必须腾出空间。

如果没有进程优先级,面临内存不足时只有两条路:要么直接触发Linux内核的OOM Killer,随机找进程杀掉;要么一直等到系统彻底卡死甚至重启。这两种结果都是灾难级的。随机杀会把正在前台使用的应用到杀掉,用户当场就崩溃。等到系统已经卡顿再杀,整个手机已经没法用了。所以Android必须提前给所有进程排队打分,明确“谁该舍、谁该留”。

1.2 优先级就是“排队被杀”的号码牌

很多资料把进程优先级翻译成“被杀的顺序”,其实它是一个动态变化的评分体系。系统给每个进程算出一个分数,分数越低越重要,越不容易被回收;分数越高越次要,内存一紧就越先被清理。你可以把它想象成租房时的预约名单,房间不够时,排在后面的先出去,早期看不出来,真到临界点时,名单顺序决定一切。

这个分数在现代Android里一般反映在/proc/<pid>/oom_score_adj这个文件里,取值通常在 -1000 到 1000 之间。进程不会永远保持同一个分数,它会跟前台有没有Activity、有没有被别的进程绑定、有没有运行前台服务、甚至退出后台多久都有关。系统会定期重新计算分数,用来精确控制每轮内存回收该动哪些进程。理解这套机制,是你处理好进程生命周期的基础。

2. Android进程优先级到底怎么分

2.1 官方给出的五档进程分类

Android官方把进程分为五档,按重要性从高到低依次是:前台进程、可见进程、服务进程、后台进程、空进程。

  • 前台进程:正在用户屏幕最顶层运行的Activity、正在执行生命周期回调的BroadcastReceiver,或者正在执行关键回调的Service,用户能直接感受到它。只要不是系统实在撑不住,这类进程通常不应该被杀。
  • 可见进程:界面部分可见,但没有完全处于交互状态。比如被一个半透明弹窗遮住的Activity,或者输入法、动态壁纸这类辅助窗口。用户还能看到它,所以重要性也很高。
  • 服务进程:通过startService启动的服务,不在前台界面也无法直接可见,但后台还在做用户关心的事,比如播音乐、下载。系统一般愿意多留一留。
  • 后台进程:用户按了Home或者切走,Activity已经不可见,但进程还保留着。这类进程随时可能被杀。
  • 空进程:进程里没有Activity、Service等任何运行组件,只留在内存里当缓存,已经成了纯粹的资源占用者,回收时优先级最低。

2.2 从oom_adj到oom_score_adj,数值越高兴越快被回收

老版本Android用的是内核里比较粗的oom_adj,范围 -16 到 15,数值越小级别越高。后来系统改成了更线性的oom_score_adj,范围基本在 -1000 到 1000,好处是计算起来更平滑,也更方便在框架层做微调。

我整理过一份常见的参考数值,不同手机厂商和不同Android版本会有差异,但结构基本一致:

进程状态典型oom_score_adj
系统持久进程约 -800
正在交互的前台应用0
可见进程约 100
前台服务(带通知,但不在前台)约 50
普通后台服务约 200
后台Activity约 400
空进程 / 缓存进程约 900 到 1000

注意,这些数字不是固定死的。不同ROM会在系统进程、厂商应用、白名单应用上做额外调整,但“数值越大越容易被回收”这个基本方向不变。所以当你调试自己应用时,看到oom_score_adj从0变成400,就意味着它已经从“正在交互”降级成了“后台可回收”的对象。

2.3 优先级不是固定不变的,它会跟着组件状态动态变化

很多人写App时会有个误区:以为一个Service启动后,进程就一直是“服务进程”,永远不会变。实际上进程优先级由进程内当前所有组件的最高重要性决定,而且会跟随组件生命周期实时变化。

举个例子:你的App里有一个前台Activity正在运行,此时进程优先级是0。用户按Home键,Activity进入onStop,进程变成了“后台进程”,adj可能直接跳到400。如果同一进程里刚好有个服务在播放音乐,且通过前台服务方式启动,那么进程优先级又会提升到一个较高的档位。如果服务只是普通startService,那它只能让进程在“服务进程”和“后台进程”之间略微挣扎,并不能保证不被回收。

另外,如果另一个前台应用绑定了你这个App的Service,比如系统MediaBrowserService被音乐App连接,你的进程会跟着绑定者的优先级走。这就是为什么有时候你的应用明明在后台,adj却很漂亮,因为它“沾了光”。

3. 系统是怎么把低优先级进程“请走”的

3.1 lmkd的诞生:从内核驱动到守护进程

早期Android使用的回收机制叫lowmemorykiller,是一个内核对进程的判定直接杀人的模块。它会定期检查可用内存剩余量,再对照配置的内存阈值和adj阈值,一旦剩余内存低于某个水位,就把超过对应adj的进程杀掉。低版本上它工作得还行,但有个明显问题:它只是简单看剩余内存,不能很好感知“内存压力到底有没有在累积”。

后来系统引入了lmkd(Low Memory Killer Daemon),这是一个用户空间的守护进程。它一方面能从内核拿到更精细的内存压力信息,比如PSI(Pressure Stall Information),也就是系统在内存上发生阻塞的时间和程度;另一方面可以更灵活地执行内存回收策略,目标还是那些adj值较高的进程,一旦选中就直接发SIGKILL。现在绝大多数Android设备都是用lmkd配合内核watermark来工作的。

3.2 一次真实的内存回收过程

我在调试某款中端设备时遇到过这样的场景:手机运行视频通话App(前台),后台堆了新闻客户端、购物App、游戏、地图导航等多个应用。随着通话时间拉长,系统可用内存逐渐下降,lmkd开始介入。

首先被清掉的,一定是我进程列表里那些adj接近1000的空进程,它们连Activity都没有了,回收无成本。接着是很多后台缓存Activity进程,也就是常见的一堆App虽然看不到界面,但进程还活着;系统杀掉它们时,如果你回去打开对应应用,会看到重新走启动页、重新恢复数据,这就是典型的“进程被回收了”。

然后可能轮到一个只做普通后台任务、没有前台服务也没有可见界面的应用。如果它还在后台挂着一个Service,adj大约200多,在内存进一步紧张时也会被处理。而正在通话的App因为属于前台进程,只要用户还看着界面,lmkd一般不会动它。

3.3 进程被杀之后,系统如何帮你恢复现场

Android进程被系统杀掉不是无痕的。只要进程之前是通过正常栈启动,系统会在用户重新进入应用时,尝试恢复到被杀前的Activity栈。它会读取Activity在onSaveInstanceState里保存的状态,重建Activity和View,再通过onCreate里的savedInstanceState恢复临时数据。

但这里必须说明:这种恢复不是百分百无损。如果应用在进程被杀之前没有处理好状态保存,比如一些内存里的集合、请求队列或者WebSocket连接,恢复后就会丢失。所以要保证进程被系统回收后依然体验正常,重点不是“让进程永远不死”,而是做好状态保存和重建时的恢复逻辑。你可以在onSaveInstanceState、onTrimMemory里保存数据,也可以在Application里维护一个可持久化的临时状态。

4. 开发者如何合理影响自己的进程优先级

4.1 前台服务:合法“提权”最基本的手段

如果应用需要在后台执行用户能明确感知的任务,比如下载大文件、播放音频或录制视频,最标准的方式是开启前台服务并调用startForeground()。前台服务会持有一条常驻通知,让用户知道当前有任务在执行,同时系统的优先级也会相应提升,adj值会明显低于普通后台服务。

用Kotlin写一个典型示例:

class DownloadService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { startForeground( NOTIFICATION_ID, createNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC ) } else { startForeground(NOTIFICATION_ID, createNotification()) } // 在这里执行下载任务 return START_STICKY } }

Android 14开始,前台服务必须声明类型,并且部分类型要在启动时满足系统要求。比如下载任务需要声明FOREGROUND_SERVICE_TYPE_DATA_SYNC,并且从Android 14某个版本开始,某些后台启动前台服务的情况会被系统直接拦截。所以正确做法不是拼手速去绕过,而是在用户主动操作时启动服务,或用系统允许的调度方式(比如WorkManager满足条件时运行)。

4.2 绑定关系带来的优先级提升

除了前台服务,另一个重要手段是“绑定”。当一个高优先级进程绑定到你应用的Service,或者调用你应用的ContentProvider时,你的进程adj会被重要的一方带着往上抬。这个机制经常被忽略,但它非常实用。

比如App里播放器提供一个媒体播放Service,通过MediaStyle通知绑定到系统MediaSession,用户在前台控制播放时,播放Service的进程就能跟着保持较高优先级。再比如,你的App给主应用提供数据能力,作为一个独立进程运行ContentProvider,主应用每次调用时,你的Provider进程都会因为主应用处于前台而临时获得较高优先级。

这个机制也有代价:如果你绑定的客户端进程本身很弱,比如只是一个后台缓存进程,那你的服务顶多从“空进程”等级变成“服务进程”,并不能保证绝对安全。所以判断到底该用前台服务还是绑定,需要结合业务场景思考,而不是单纯为了提高优先级硬绑。

4.3 千万别做的“保活”误区

我见过不少开发者为了不让进程死,会做各种“保活”操作:在Service里循环空转、开一个常驻线程跑心跳、监听系统广播把自己拉活、甚至做双进程互相守护。说句实在话,这些方案在早期Android版本上可能还有部分作用,放到现在,轻则被系统电量和后台限制策略直接清理,重则被应用商店、用户当作流氓应用处理。

系统真正在意的是“用户体感”。你现在就算能让进程一直活着,但如果应用占着内存不做任何有意义的事,系统耗电增加,用户也会去系统设置里管理你的应用。合理的做法应该是:让任务变成前台服务、绑定从而提升优先级,或者干脆不用常驻进程,用JobScheduler、WorkManager、推送通道在合适的时机唤醒执行。进程优先级的存在,本来就不是为了让所有进程永远活着的。

5. 进程优先级的调试与排查实录

5.1 用adb查看进程现任adj

排查问题第一步,是知道自己进程当前到底处于什么优先级。最简单的方式是使用Android自带的dumpsys命令:

adb shell dumpsys activity processes | grep -E "oomScoreAdj |pid.*com.example.app"

输出里会包含一串类似这样的信息:

*APP* UID 10086 PID 12345 com.example.app oomScoreAdj=0 lastActivityTime=-1h ...

看到oomScoreAdj=0说明你现在是前台进程;如果切后台后再跑一次,可能会变成oomScoreAdj=400或更高。有些设备上普通adb shell没有权限读其他应用进程,但看自己应用进程通常是没问题的。

如果发现看不到oomScoreAdj,可以用另一个命令直接看内核文件:

adb shell cat /proc/12345/oom_score_adj

这个方法需要知道进程PID,适合在已经拿到PID后快速确认。不过要注意,部分系统为了安全,普通shell可能临时降权,读不到其他uid的进程节点。这种情况下优先用dumpsys。

5.2 复现一次“被回收”现场

想实测自己应用的进程优先级变化,可以在开发机上做一个简单实验。把应用切到后台,然后让系统产生内存压力;最直接的方式是把其他大型应用一个个打开并切到后台,直到可用内存越来越少。也可以使用开发者选项里的“不保留活动”,模拟系统回收Activity。

我在测试某项目时遇到过:App里有下载任务,用普通Service开在后台,切后台后oom_score_adj大约在200左右。我连续打开了相机、地图、购物和几个游戏,再回来看dumpsys时,发现下载Service所在进程的oomScoreAdj已经变成1000左右,没过多久就被lmkd杀掉了。之后我把这个Service改成前台服务,重新复现同一场景,发现adj能稳定在50附近,整个测试过程没被杀。这说明通过调试找到业务真正的前台化空间,比盲目保活有用得多。

5.3 在代码里监测进程状态

有些应用需要在进程被判死刑前做最后的数据保存,这可以通过onTrimMemory(int level)回调感知。当level为TRIM_MEMORY_RUNNING_LOW时,说明当前还有Activity在前台,但系统已经内存紧张;当level为TRIM_MEMORY_UI_HIDDEN时,说明你的应用已经退到后台,是时候释放不必要的缓存了;当收到TRIM_MEMORY_BACKGROUND及以上,说明进程已经开始排队等待被系统回收,这时候应该保存业务关键数据。

注意,onTrimMemory回调顺序和进程被杀时间不完全对应,不要指望靠它做“临死抢救”。它更适合做资源整理,比如清掉图片缓存、关闭部分网络连接,让进程在后台更“轻”,从而降低被杀概率,或者至少让崩溃后的恢复成本变低。把这些数据保存逻辑放在onPause和onStop里,比收到回调再动手更可靠。

6. 常见问题与避坑指南

6.1 为什么有Service还是被杀

很多人的第一反应是:我开了Service,怎么还会被杀?答案在于普通Service的优先级通常只是“服务进程”档位,当内存压力大,系统会继续提升回收力度,这一档并不能保命。只有前台服务,也就是带通知、调用过startForeground()的Service,才会有比较强的生存能力。

我之前帮一个团队成员排查过类似问题:他们做了一个联网状态监听,用startService常驻,结果在后台运行一段时间后进程消失。dumpsys日志里显示的oomScoreAdj一度接近后台缓存进程。后来我们把监听逻辑并入了一个需要用户主动确认的前台服务,进程才稳定下来。实际开发中,如果业务确实需要后台长期运行,最好先检查有没有实际的前台场景可以绑定,比如用户在看视频、在听音频、在进行上传下载。

6.2 前台服务为什么也会被系统“清掉”

不少人也遇到过前台服务被回收的情况。这个可能因为:第一,前台服务的类型不符合系统要求,例如Android 14里声明了不支持的启动类型;第二,用户主动在系统设置里关闭了这个App的通知或后台运行权限;第三,部分国产ROM有更激进的清理策略,会把长时间后台运行的前台服务也杀掉。

遇到这类问题,先不要急着怪系统。你可以先查一下应用有没有在用户屏幕解锁后偷偷后台启动服务,如果有,那被限制很正常。没有的话,可以在崩溃日志里看是否有ServiceConnection断开等相关记录,也可以配合dumpsys看最近的系统进程清理日志。关键是做好业务降级:如果服务必须运行,就通过系统提供的调度能力定时重试;如果服务只是辅助,就要接受它可能被杀的事实,保证用户重新进入时立刻重启。

6.3 进程优先级不是保命符

最后想强调一点:优先级只是系统在内存总量紧张时评估“先放弃谁”的标准,它不能保证你的应用永远不死。正常使用时,系统不会杀死前台进程,也不应该频繁杀死前台进程;但当某些系统进程、安全组件出问题时,为了不让整机完全死机,系统依然可能强行回收。因此不要给进程优先级“镀金”,它是App质量的辅助要素,不是免死金牌。

我在实际项目中经常看到团队为了“不杀进程”,牺牲启动速度、电量和用户隐私,最后被用户卸载。反而是那些启动快、数据恢复好、后台任务少的应用,用户压根不会在意它是不是被回收过。从这个角度看,进程优先级再高,也不如把活干完、把状态存好、把恢复做顺。

我个人在实际开发里的习惯是:凡是后台任务,先想清楚“是否真的有前台感知”;没有,就交给系统的Job机制去调度;有,就正正经经做成前台服务。调试时用dumpsys观察几个关键节点,并专门做一次“后台空转测试”,模拟内存紧张,看看申请结果如何。这个办法帮我提前发现过不少数据丢失和崩溃问题,也避免了很多无意义的“保活改造”。你也可以从今天开始,把自己App的各个进程adj全扫一遍,很可能会有意外发现。

相关新闻

OpenClaw Skills深度解析:从元数据设计到沙箱权限的完整指南

OpenClaw Skills深度解析:从元数据设计到沙箱权限的完整指南

1. Skills 在 OpenClaw 里的定位&#xff1a;先搞懂它到底解决了什么问题接触 OpenClaw 的朋友应该都有这种感觉&#xff1a;默认装好之后&#xff0c;它确实能聊天、能总结、能写代码&#xff0c;但真要它去操作点实际的东西——比如帮你批量重命名一整个目录的文件、定时抓某…

2026/10/20 7:45:13 阅读更多 →
LangGraph时间旅行:基于checkpointer的Agent状态回放与分支探索

LangGraph时间旅行:基于checkpointer的Agent状态回放与分支探索

如果你用 LangGraph 搭过 Agent&#xff0c;八成会遇到这种场景&#xff1a;图跑到一半&#xff0c;结果完全不符合预期&#xff0c;你想知道“中间到底哪一步把状态带偏了”&#xff0c;甚至想把整个流程倒回去&#xff0c;改掉中间某个节点的产物&#xff0c;再重新跑一遍。L…

2026/10/20 7:45:13 阅读更多 →
JMeter 压力测试从入门到进阶:吞吐量指标到分布式压测的实战链路

JMeter 压力测试从入门到进阶:吞吐量指标到分布式压测的实战链路

JMeter 压力测试这个词&#xff0c;我过去七八年接触过太多次。无论是刚入门的新人还是带团队的老手&#xff0c;聊起性能测试基本都会提到 JMeter&#xff0c;但真正能把它用明白的人&#xff0c;说实话不多。很多人下载下来点几下&#xff0c;线程数填个 100&#xff0c;循环…

2026/10/20 7:44:12 阅读更多 →

最新新闻

腾讯云ASR实时语音识别前端接入:WebSocket签名与音频处理实战

腾讯云ASR实时语音识别前端接入:WebSocket签名与音频处理实战

前阵子我在给一个内部工具加“实时转写”功能&#xff0c;要把对话语音实时转成文字用于内容分析。调研了一圈&#xff0c;最后选了腾讯云 ASR 实时语音识别。原本以为就是“拿麦克风录音&#xff0c;发到 WebSocket&#xff0c;收文本”三件事&#xff0c;实际做下来发现每个环…

2026/10/21 3:54:34 阅读更多 →
Linux V4L2视频采集四步流程:打开→查询→设置→启动

Linux V4L2视频采集四步流程:打开→查询→设置→启动

1. 项目概述&#xff1a;为什么V4L2是Linux视频设备的“底层语言”在Linux系统里&#xff0c;但凡你接触过USB摄像头、树莓派CSI模组、工业面阵相机&#xff0c;甚至某些PCIe采集卡&#xff0c;几乎绕不开一个词&#xff1a;V4L2。它不是某个具体软件&#xff0c;也不是命令行工…

2026/10/21 3:54:34 阅读更多 →
Flutter GestureDetector 手势系统深度解析:从原理到高性能实践

Flutter GestureDetector 手势系统深度解析:从原理到高性能实践

1. 为什么说 GestureDetector 是 Flutter 手势世界的“总开关”在 Flutter 开发中&#xff0c;你写过多少次onTap&#xff1f;又是否曾疑惑&#xff1a;明明只是点了一下屏幕&#xff0c;背后却触发了onTapDown、onTapUp、onTapCancel一整套回调&#xff1f;或者&#xff0c;你…

2026/10/21 3:54:34 阅读更多 →
Qwen2.5-VL跨硬件微调:LoRA与OFT在昇腾910B与4090上的实战

Qwen2.5-VL跨硬件微调:LoRA与OFT在昇腾910B与4090上的实战

这个项目的起因很现实&#xff1a;手上的多模态微调代码在单张4090上调得好好的&#xff0c;业务方突然要求国产算力平台也能跑&#xff0c;而基于Qwen2.5-VL的私域图像理解任务又必须保留原有效果。于是就有了标题里那条主线——从LoRA到OFT&#xff0c;从昇腾910B到4090&…

2026/10/21 3:54:34 阅读更多 →
深入Linux内存管理:伙伴系统与slab分配器核心原理

深入Linux内存管理:伙伴系统与slab分配器核心原理

前段时间在压测一个存储服务时&#xff0c;我发现一个奇怪的现象&#xff1a;明明内存总量还很充足&#xff0c;但每次接口申请一个8KB的连续块时&#xff0c;耗时总会偶发冲到几百微秒甚至毫秒级。查到最后&#xff0c;问题不在业务代码&#xff0c;而在内存管理这一层——更具…

2026/10/21 3:54:34 阅读更多 →
FFmpeg输入源处理:本地文件与网络流读取的底层逻辑与实战

FFmpeg输入源处理:本地文件与网络流读取的底层逻辑与实战

FFmpeg 这个工具&#xff0c;刚接触音视频开发的人往往会被它庞大的参数体系劝退&#xff0c;但真正用起来之后又会发现&#xff0c;很多看似复杂的需求&#xff0c;其实一条命令就能搞定。这次要聊的是 FFmpeg 读取本地文件和网络流这两种输入源的处理方式&#xff0c;属于系列…

2026/10/21 3:53:34 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →