Android Binder IPC 机制详解:从设计原理到跨进程调用实战
1. 从一个“看不见的快递员”说起Binder IPC到底在忙什么如果你写过Android应用大概率遇到过这样的场景调用一个系统服务的方法比如获取设备信息、启动一个Activity代码里只是一行简单的函数调用但背后其实发生了一次跨越进程边界的通信。这个“跨越边界”的动作就是IPCInter-Process Communication进程间通信。而Binder就是Android系统里承担这个任务的核心机制。打个比方。假设你住在一栋大楼里你的房间是“应用进程”物业办公室是“系统服务进程”。你不能直接闯进物业办公室翻文件但你可以填一张申请单交给前台前台帮你转交物业处理完再把结果通过前台送回给你。Binder就是这套“前台申请单回执”的完整体系。它让不同进程之间可以像调用本地函数一样调用远程函数开发者几乎感觉不到进程边界的存在。这个机制解决的核心问题是安全、高效地实现跨进程调用。Android为什么要自己搞一套Binder而不用Linux现成的管道、消息队列、共享内存或者Socket原因很实际——移动端对性能和安全性极其敏感。传统IPC机制要么拷贝次数多性能差要么缺乏身份校验安全性弱要么使用复杂开发效率低。Binder在性能和安全之间找到了一个很好的平衡点一次拷贝、内核级身份校验、面向对象的调用接口。这篇文章适合谁看如果你正在准备Android系统开发相关的面试或者在做系统层、Framework层的开发工作又或者你单纯好奇“为什么Android要用Binder而不用其他IPC”那这篇内容就是写给你的。我会从设计思路、核心原理、代码实操、问题排查几个维度把Binder拆开揉碎讲清楚。不堆砌源码但关键流程一个不落。2. 为什么是Binder设计取舍与核心架构拆解2.1 传统IPC的短板与Binder的破局思路要理解Binder的价值得先看看没有它的时候Linux世界是怎么做IPC的。管道和消息队列的本质是内核维护一块缓冲区发送方写入接收方读取数据要从用户空间拷贝到内核空间再从内核空间拷贝到另一个用户空间两次拷贝。共享内存虽然避免了拷贝但多个进程直接映射同一块物理内存谁都能改安全性几乎为零而且使用起来需要自己处理同步问题。Socket更灵活但开销大适合网络通信而非高频的本地进程间调用。Binder的设计思路很明确保留一次拷贝的效率优势同时在内核层加入严格的身份校验。具体来说Binder驱动在内核空间维护了一个“接收缓存区”发送方通过copy_from_user把数据拷贝到内核缓冲区接收方直接从这个内核缓冲区读取数据不需要再拷贝回用户空间。这就是所谓的“一次拷贝”。同时Binder驱动在传输数据时会附带发送方的PID和UID接收方可以据此判断对方身份决定是否响应。注意这里说的“一次拷贝”是相对于传统IPC的两次拷贝而言的。实际上Binder在传输大文件描述符等特殊数据时会有额外处理但常规数据传输确实只经历一次用户态到内核态的拷贝。2.2 Binder架构的四层模型Binder的架构可以分成四层来理解从下往上依次是内核层Binder驱动位于内核空间负责最底层的数据传输、内存管理、线程调度和身份校验。它以一个字符设备/dev/binder的形式存在用户态程序通过ioctl系统调用与它交互。C层libbinder提供面向对象的封装包括IBinder、BpBinder、BBinder、ProcessState、IPCThreadState等核心类。这一层是Native开发者和Framework开发者最常打交道的。Java层Binder Framework通过JNI与C层对接提供IBinder、Binder、BinderProxy、Parcel等Java类供应用层开发者使用。应用层开发者通过AIDLAndroid Interface Definition Language定义接口编译工具自动生成Stub和Proxy类屏蔽底层通信细节。这四层各司其职内核层保证效率和安全的底线C层和Java层提供开发便利性应用层让开发者只需关注业务逻辑。理解这个分层结构对后续排查问题非常关键——不同层出的问题排查手段完全不同。2.3 Binder通信中的四个核心角色一次完整的Binder通信涉及四个角色我用一个实际场景来串讲应用进程要调用系统服务获取当前时间。Client客户端发起调用的进程也就是应用进程。它持有服务端的一个“代理对象”Proxy调用代理对象的方法时代理会把参数打包成Parcel然后通过Binder驱动发送出去。Server服务端实际提供服务的进程比如系统的时间服务进程。它持有一个“本地对象”Stub/BBinder真正执行方法逻辑。ServiceManager服务管理器相当于电话簿。服务端启动时先向ServiceManager注册自己“我叫时间服务我的Binder句柄是1”客户端需要时向ServiceManager查询“时间服务的句柄是多少”拿到句柄后才能发起通信。Binder驱动整个通信的“交通枢纽”负责在Client和Server之间传递数据同时完成线程管理和身份校验。这四个角色的协作流程是Server注册 → Client查询 → Client发起调用 → 驱动转发 → Server处理 → 结果回传。每一步都有细节后面会逐一展开。3. 核心机制深挖一次拷贝、线程池与引用计数3.1 内存映射与一次拷贝的实现原理Binder实现一次拷贝的关键在于mmap。Binder驱动在初始化时会为每个使用Binder的进程创建一块内核缓冲区并通过mmap将这块内核缓冲区同时映射到进程的用户空间。注意这里映射的是接收方的缓冲区。发送方调用transact时数据从发送方用户空间拷贝到内核缓冲区这是唯一一次拷贝接收方因为已经把自己的用户空间和这块内核缓冲区做了映射所以可以直接读取不需要再拷贝。这就像两个人共用一块白板一个人写上去另一个人直接看不需要把内容抄一遍再传递。这个设计带来的性能优势非常明显。在早期Android设备上Binder的传输效率比Socket高出数倍比管道也快不少。但代价是内存占用——每个使用Binder的进程都需要预留一块内核缓冲区默认大小是1MB左右不同版本有差异。对于内存紧张的移动设备来说这个开销是可以接受的因为Binder通信非常频繁省下的拷贝时间远比多占的内存值钱。3.2 Binder线程池的工作机制服务端进程并不是每来一个请求就创建一个线程。Binder驱动为每个Server进程维护了一个线程池默认最大线程数是16个可以通过ProcessState::setThreadPoolMaxThreadCount调整。当Client发起请求时如果Server端没有空闲线程驱动会唤醒或创建一个新线程来处理。线程池的管理策略是主线程在joinThreadPool后进入循环等待有新请求时驱动唤醒它如果请求并发量超过当前线程数驱动会通知进程创建新线程直到达到上限。超过上限的请求会排队等待。这里有个容易踩的坑如果Server端的某个Binder方法执行时间过长会占住一个线程并发请求多了之后线程池耗尽后续请求全部阻塞。我见过不少案例开发者在一个Binder服务方法里做了网络请求或者大量IO操作结果导致整个系统服务卡死。正确的做法是把耗时操作放到工作线程里异步执行Binder方法本身只做参数校验和任务分发。实操心得在开发系统服务时如果某个方法可能耗时超过几毫秒建议用HandlerThread或者线程池异步处理Binder方法立即返回。这样既避免了线程池耗尽也提升了响应速度。3.3 引用计数与生命周期管理Binder对象的生命周期靠引用计数来管理。每个Binder对象在内核中都有一个引用计数Client持有代理对象时计数加一释放时减一。当计数归零时Binder驱动会通知Server端可以销毁对应的本地对象。这个机制听起来简单但实际使用中有两个经典问题循环引用两个Binder对象互相持有对方的代理导致引用计数永远不归零内存泄漏。跨进程死亡通知Client需要知道Server什么时候挂了。Binder提供了linkToDeath机制Client可以注册一个死亡接收器当Server进程退出时驱动会通知ClientClient可以清理资源或尝试重连。// Java层注册死亡通知的典型写法 IBinder binder ServiceManager.getService(my_service); binder.linkToDeath(new IBinder.DeathRecipient() { Override public void binderDied() { // 服务进程挂了在这里做清理或重连 binder.unlinkToDeath(this, 0); } }, 0);这段代码看起来简单但实际项目中很多人忘了在binderDied里调用unlinkToDeath导致死亡接收器本身泄漏。另外linkToDeath必须在Binder还活着的时候调用如果调用时服务已经死了会直接抛出DeadObjectException。4. 手把手实操从AIDL到跨进程调用全流程4.1 AIDL接口定义与编译产物解析AIDL是Android提供的接口定义语言开发者只需要写一个.aidl文件编译工具就会自动生成Stub和Proxy类。假设我们要定义一个计算两个数之和的服务// ICalculate.aidl package com.example.demo; interface ICalculate { int add(int a, int b); }编译后会生成ICalculate.java里面包含三个关键部分ICalculate接口继承IInterface声明了add方法。ICalculate.Stub抽象类继承Binder并实现ICalculate。服务端需要继承它并实现add方法。它内部有一个asInterface静态方法用于把IBinder转换成ICalculate接口。ICalculate.Stub.Proxy代理类实现了ICalculate。客户端拿到的就是这个代理对象调用add时代理会把参数写入Parcel调用transact发送然后读取返回结果。asInterface的逻辑值得关注如果传入的IBinder是本地对象同一个进程直接强转返回如果是远程代理跨进程则创建Proxy对象包装后返回。这个判断通过queryLocalInterface完成是Binder优化同进程调用的关键——同进程调用不走驱动直接走本地方法调用效率极高。4.2 服务端实现与注册流程服务端的实现分三步继承Stub、实现方法、注册到ServiceManager。public class CalculateService extends ICalculate.Stub { Override public int add(int a, int b) { return a b; } public void register() { // 注册到ServiceManager名字叫calculate ServiceManager.addService(calculate, this); } }ServiceManager.addService是一个跨进程调用它会通过Binder驱动把服务端的Binder对象引用传递给ServiceManager进程。ServiceManager内部维护一张表记录服务名到Binder句柄的映射。这里有个细节服务注册的名字必须唯一重复注册会抛异常。另外注册的Binder对象必须是BBinder的子类Java层就是Binder的子类否则驱动不认。4.3 客户端调用与数据打包过程客户端获取服务并调用的代码IBinder binder ServiceManager.getService(calculate); ICalculate calc ICalculate.Stub.asInterface(binder); int result calc.add(3, 5); // 返回8看起来就是普通方法调用但calc.add(3, 5)实际执行的是Proxy.add// Proxy.add的内部实现简化 public int add(int a, int b) { Parcel data Parcel.obtain(); Parcel reply Parcel.obtain(); try { data.writeInterfaceToken(DESCRIPTOR); data.writeInt(a); data.writeInt(b); mRemote.transact(TRANSACTION_add, data, reply, 0); reply.readException(); return reply.readInt(); } finally { data.recycle(); reply.recycle(); } }transact是核心调用它会通过JNI进入Native层最终调用Binder驱动的ioctl。数据打包用Parcel这是一个高效的序列化容器支持基本类型、字符串、数组、Binder对象等。注意Parcel.obtain()和recycle()的配对使用——Parcel对象池有限用完不回收会导致池耗尽后续obtain阻塞。注意writeInterfaceToken写入的是接口描述符服务端会校验这个描述符是否匹配防止客户端调用错误的接口。这是Binder安全机制的一部分。4.4 完整通信时序与关键参数把上面的流程串起来一次完整的Binder调用时序如下Client调用Proxy.add(3, 5)参数写入Parcel。Client调用transact通过JNI进入Native层。Native层调用IPCThreadState::transact构造binder_transaction_data结构体。通过ioctl(BINDER_WRITE_READ)把数据发送给Binder驱动。驱动根据目标句柄找到Server进程把数据放入Server的接收缓冲区唤醒Server线程。Server线程从IPCThreadState::talkWithDriver返回读取数据调用BBinder::transact。BBinder::transact根据TRANSACTION_add找到对应的onTransact方法执行add逻辑。结果写入replyParcel通过驱动回传给Client。Client从transact返回读取reply中的结果。关键参数方面transact的第四个参数是flags常用的有FLAG_ONEWAY单向调用不等待返回适合通知类场景和0双向调用等待返回。FLAG_ONEWAY能显著提升吞吐量但要注意它不保证顺序也不返回异常。5. 常见问题与排查技巧实录5.1 典型异常与错误码速查Binder相关的异常和错误码不少我整理了一张速查表覆盖最常见的几种异常/错误码含义常见原因排查方向DeadObjectException目标Binder对象已死亡服务进程崩溃或被杀死检查服务进程日志确认是否OOM或异常退出TransactionTooLargeException传输数据过大Parcel超过1MB限制减少传输数据量大文件用文件描述符传递SecurityException权限校验失败调用方UID/PID无权限检查服务端权限校验逻辑和调用方权限声明NullPointerExceptionasInterface后服务未注册或获取失败ServiceManager中无此服务确认服务注册时机检查服务名拼写RemoteException远程调用失败多种原因需看具体message结合日志和错误码进一步定位TransactionTooLargeException是我见过最多的问题之一。Binder的传输缓冲区默认1MB左右但这是所有并发传输共享的不是每次调用独享。如果同时有多个大传输很容易触发。解决方案包括压缩数据、分批传输、用ParcelFileDescriptor传递文件描述符而非文件内容。5.2 死锁与线程阻塞的排查思路Binder死锁的经典场景是进程A的Binder线程调用进程B的方法进程B的Binder线程又回调进程A的方法而进程A的线程池已满无法处理回调双方互相等待。排查这类问题第一步是抓取Binder调用栈。可以通过dumpsys binder或者cat /sys/kernel/debug/binder/transactions查看当前活跃的Binder事务。第二步是分析线程状态用kill -3触发ANR日志或者用调试工具抓取Native堆栈。预防死锁的经验避免在Binder方法中同步调用另一个Binder服务。如果必须调用考虑用FLAG_ONEWAY异步化或者把调用放到独立线程中。另外服务端线程池大小要合理评估高并发场景下适当调大。5.3 性能优化的几个实操技巧Binder性能优化有几个立竿见影的手段减少传输数据量只传必要字段避免传大对象。能用int就不用String能用数组就不用List。使用FLAG_ONEWAY通知类、日志类调用不需要返回值用单向调用能大幅提升吞吐。复用Parcel虽然Parcel有对象池但高频调用场景下手动复用能减少GC压力。避免同进程走Binder同进程调用直接走本地接口asInterface已经做了优化但前提是queryLocalInterface返回非空。如果自己实现Binder时覆盖了queryLocalInterface返回null同进程调用也会走驱动白白浪费性能。实操心得在调试Binder性能时可以用atrace抓取Binder相关的trace点能看到每次调用的耗时和调用方。我试过在一个高频调用场景下把双向调用改成单向调用吞吐量直接翻了三倍。6. 从源码到实战几个容易忽略的细节6.1 Binder驱动中的红黑树与等待队列Binder驱动内部用红黑树管理所有Binder节点和引用用等待队列管理阻塞的线程。红黑树保证了查找效率是O(log n)这在Binder对象数量庞大时很重要。每个binder_proc结构体代表一个使用Binder的进程内部有threads红黑树和nodes红黑树。理解这个数据结构对排查问题有帮助当出现Binder泄漏时/sys/kernel/debug/binder/proc下会显示每个进程的Binder对象数量如果某个进程的node数量持续增长说明有Binder对象没释放。6.2 Java层与Native层的对象映射关系Java层的Binder对象和Native层的BBinder是一一对应的通过JNI的long字段持有Native指针。BinderProxy对应Native的BpBinder。这个映射关系在跨层调试时很关键——Java堆栈里看到的BinderProxy在Native堆栈里对应的是BpBinder。有个常见误区认为Java层的Binder对象就是Binder驱动里的binder_node。实际上binder_node是内核层的概念Java层的Binder只是用户态的一个代理真正在内核里代表这个Binder对象的是binder_node。三者是不同层次的东西排查问题时要注意区分。6.3 一次拷贝的边界条件与例外前面说Binder是一次拷贝但这个结论有边界条件。当传输的数据中包含文件描述符时Binder驱动需要特殊处理——文件描述符不能直接拷贝驱动会在目标进程中创建一个新的文件描述符指向同一个文件。这个过程涉及额外的内核操作不是简单的一次拷贝。另外当数据量超过一定阈值时Binder可能会采用不同的传输策略。虽然常规数据是一次拷贝但不要把它当成绝对真理具体场景要具体分析。我在实际项目中遇到过传输大量数据时性能骤降的情况最后发现是数据量接近缓冲区上限驱动频繁触发等待和唤醒效率反而比小数据量时低很多。7. 写在最后一些个人体会Binder这套机制我前前后后研究了挺长时间从最开始看AIDL生成的代码一脸懵到后来能对着Binder驱动源码梳理流程中间踩过的坑不少。最大的体会是Binder的复杂度不在于单个环节而在于环节之间的衔接。单独看transact、Parcel、ServiceManager都不难但把它们串起来理解一次完整调用需要反复对照源码和实际日志。另一个体会是排查Binder问题时日志和堆栈比源码更管用。源码告诉你“应该怎样”日志告诉你“实际怎样”。我习惯在关键路径上加日志比如服务注册时打印句柄、调用前后打印时间戳这些日志在出问题时能快速定位是哪个环节卡住了。最后分享一个小技巧如果你在开发系统服务建议在服务端加一个“健康检查”方法客户端定期调用既能检测服务是否存活也能顺便统计调用延迟。这个方法用FLAG_ONEWAY实现开销极小但能提前发现很多潜在问题。这个做法我在几个项目里都用过实测下来很稳。

相关新闻

.NET Core对接用友凭证API的健壮性设计与财务语义校验

.NET Core对接用友凭证API的健壮性设计与财务语义校验

1. 项目概述:为什么用友凭证API对接成了财务系统集成的“分水岭”在某高校实验室做财务中台项目时,我第一次被财务同事拉进会议室,桌上摊着三份不同版本的用友U8凭证接口文档——U8V10.1、U8V13.0、U8Cloud,每份文档里“新增字段”…

2026/10/15 16:23:09 阅读更多 →
Unity FPS游戏框架开发实战:角色控制器、武器射击与AI状态机全解析

Unity FPS游戏框架开发实战:角色控制器、武器射击与AI状态机全解析

简介:一套可在 Unity3D 中直接运行的 FPS 游戏完整工程源码,面向希望掌握第一人称射击玩法和联机对战实现的中初级开发者,可用于学习项目搭建与功能拆解。压缩包内共 1609 个文件,其中包含大量场景与资源索引用的 bin、info、meta…

2026/10/15 16:22:03 阅读更多 →
成为全栈·Flutter App 篇·服务端目录与文章辅助阅读:锚点、上下篇、浏览量和阅读历史

成为全栈·Flutter App 篇·服务端目录与文章辅助阅读:锚点、上下篇、浏览量和阅读历史

成为全栈Flutter App 篇服务端目录与文章辅助阅读:锚点、上下篇、浏览量和阅读历史 上一篇解决了"目录项怎么绑到标题上"。这篇接着说文章页里其余那些看起来都很小、但每个都有自己的坑的功能:目录面板、上下篇、浏览量、阅读历史。 四个功…

2026/10/15 16:22:03 阅读更多 →

最新新闻

汉字笔顺动画教学系统:基于国标规范的交互式训练实践

汉字笔顺动画教学系统:基于国标规范的交互式训练实践

简介:Hanzi Writer 是一个基于 TypeScript 开发的开源汉字笔画顺序动画与练习测验 JavaScript 库,面向中文学习者、教育类应用开发者及前端技术实践者,解决汉字书写规范可视化与交互式训练缺失的问题,特别适配简繁体字教学场景。资…

2026/10/16 20:31:58 阅读更多 →
EAC抓轨实战:精确流、偏移校正与无损FLAC转换全解析

EAC抓轨实战:精确流、偏移校正与无损FLAC转换全解析

简介:EAC CD抓轨软件压缩包是一套面向音频发烧友、音乐收藏者及数字音频制作者的经典抓轨工具,专为解决CD音轨提取时易出现的读取错误、音质损耗等问题。软件采用安全抓轨机制,能最大限度保留原始声音,支持FLAC、WAV、AAC等多种编…

2026/10/16 20:31:58 阅读更多 →
蓝色立体三角形多边形PPT背景图:选图、排版与避坑指南

蓝色立体三角形多边形PPT背景图:选图、排版与避坑指南

简介:蓝色立体三角形多边形PPT背景图片zip包,定位于需要快速提升演示文稿视觉效果的PPT制作者。以三角形拼合形成的立体图形为主视觉,蓝色调契合科技、商业、创新等专业主题,能将幻灯片的平面感转为更具层次与深度的空间感&#x…

2026/10/16 20:31:58 阅读更多 →
Foxmail v7.0.1.92:安装配置、数据迁移与避坑指南

Foxmail v7.0.1.92:安装配置、数据迁移与避坑指南

简介:Foxmail v7.0.1.92官方正式版是一款面向国内个人及办公用户的电子邮件客户端,解决邮件收发管理、垃圾邮件过滤和传输安全等常见问题。其反垃圾机制可自动识别并分拣垃圾邮件,数字签名与SSL加密确保邮件真实性和保密性,还支持…

2026/10/16 20:31:58 阅读更多 →
蔓藤植物参数化建模插件:轻量级藤本结构生成指南

蔓藤植物参数化建模插件:轻量级藤本结构生成指南

简介:这是一款面向3D动画设计师与插件开发者的蔓藤植物建模工具,专为提升自然植被场景制作效率而设计,适用于3ds Max、Maya等主流软件中快速生成可参数化控制的逼真爬藤效果。资源包共31个文件,含10个C源码(.cpp&#…

2026/10/16 20:31:58 阅读更多 →
卷积网络Padding深度解析:Valid与Same的原理、计算与工程实践

卷积网络Padding深度解析:Valid与Same的原理、计算与工程实践

1. padding 到底在解决什么问题:从尺寸收缩到边缘信息丢失刚接触 CNN 卷积网络的时候,很多人对 padding 的第一印象是“给图片外围补一圈 0”,好像只是为了凑一个尺寸,让代码不报错。但实际上,padding 要解决的是卷积操…

2026/10/16 20:30:58 阅读更多 →

日新闻

个人 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/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 14:23:36 阅读更多 →