Android四大组件与AMS/WMS协作机制:系统服务核心原理与避坑实践
做Android开发这几年我最大的感受就是很多疑难杂症之所以难查不是代码写得多烂而是你对“四大组件”和系统服务之间那套协作机制没吃透。四大组件就像一个个打工仔干活的逻辑全写在应用进程里可它们能不能上岗、什么时候被开除、窗口怎么摆、焦点给谁全是由系统进程里的AMSActivityManagerService和WMSWindowManagerService这两个幕后老板说了算。今天这篇就围绕这套“主子与打工人”的关系把组件启动、进程调度、窗口管理这些核心链路掰开揉碎讲一遍顺便把我在实际项目里踩过的坑都拿出来晒一晒希望对处在进阶期的Android开发同学有实际帮助。1. 四大组件的角色定位与打工日常1.1 ActivityApp的“门面担当”亮屏瞬间全看它Activity是用户唯一能直接感知的组件说白了就是屏幕上那块看得见摸得着的界面。它负责承载布局、处理触摸事件、管理生命周期状态机。日常开发中它的存在感最强但也最容易出幺蛾子。举个例子你在首页点了个按钮要跳详情页代码里通常就是写val intent Intent(this, DetailActivity::class.java) startActivity(intent)这句代码跑到系统里会触发一条完整链路应用进程通过Binder把请求丢给AMSAMS解析Intent、查清单、找目标Activity的进程和任务栈然后再跨进程通知应用进程创建Activity、走onCreate、onStart、onResume。这个过程里任何一环出问题轻则闪一下白屏重则直接抛ActivityNotFoundException。Activity里最烦人的就是生命周期回调。onPause、onStop、onDestroy的时序受到系统内存压力和用户操作的双重影响不是你写完代码就能完全掌控的。我见过不少刚转Android的同学在onStop里做耗时保存结果导致页面切换卡顿。这里要记住一个原则凡是能提前做的就不要拖到生命周期回调里凡是可以在ViewModel里做的就不要写在Activity身上。1.2 Service不带UI的劳模前后台两种生存模式Service负责后台任务比如播放音乐、上传文件、轮询消息。它没有界面所以用户感知不到但它和AMS的交互一点不比Activity少。Service有两种打开方式startService和bindService。前者是“你干活去吧不用管我”应用进程调起后Service会在主线程走onStartCommand后者是“我要和你建立通道随时调用你的方法”走的是bindService回调返回一个Binder对象给调用方。这两种方式背后的系统处理逻辑完全不同。startService之后AMS会维护一个ServiceRecord跟踪这个服务该待在哪个进程、什么优先级如果进程被系统回收AMS还会根据情况考虑要不要重启服务。bindService则更讲究客户端的进程绑定状态直接影响Service的存亡最后一个客户端解绑后Service就会被销毁。真正坑人的是Android 8以后的后台限制。你如果试图在后台通过startService拉起一个服务系统会直接抛IllegalStateException。很多老项目的定时任务就是这么翻车的后来刚统一改成前台服务加通知栏常驻又要应付通知权限的合规。这里我的经验是能不用Service就不用优先考虑WorkManager如果必须用前台服务一定要先想清楚用户价值别为了保活去和系统斗智斗勇。1.3 BroadcastReceiver消息传令人静态动态两套班子BroadcastReceiver是系统和应用之间的事件广播通道。它的特点是“短平快”系统发出广播匹配的Receiver在极短时间内被回调onReceive然后就得赶紧收工。Receiver分为动态注册和静态注册。动态注册需要在代码里val filter IntentFilter(com.example.CUSTOM_ACTION) registerReceiver(myReceiver, filter)静态注册则是在Manifest里声明receiver android:name.MyReceiver android:exportedfalse intent-filter action android:namecom.example.CUSTOM_ACTION / /intent-filter /receiver动态注册的生命周期跟着注册者走页面销毁前必须unregisterReceiver不然容易内存泄漏。静态注册则开机就会让系统解析到但Android 8以后因为后台限制和隐式广播限制很多系统广播你在静态注册里根本收不到只能乖乖去动态注册。我项目里出现过一次经典事故某业务模块注册了一个动态Receiver忘了在onDestroy里反注册导致进程崩溃后系统仍然把广播往一个已经释放的Receiver身上投递最终抛出了Receiver not registered的异常。排查半天才定位到生命周期管理不严谨这个根因。1.4 ContentProvider数据管家兼跨进程快递员ContentProvider是所有组件里最容易被忽略的一个但它在系统里扮演的角色非常重。它对外提供统一的增删改查接口天然支持跨进程数据访问。你可能觉得自己业务简单根本用不上ContentProvider但别忘了一个事实你App能启动首先要经过系统对ContentProvider的初始化流程。App进程被拉起时AMS会派人到目标进程把清单里声明的所有Provider先安装一遍然后才回调Application的onCreate。所以ContentProvider不只是给别的App共享数据的它也是App进程中最早被初始化的一批组件。Provider的启动时机决定了你可以用它做很多事情比如初始化SDK、拉起核心线程。很多框架就是通过一个空壳Provider拿到App启动时机省得用户手动调用初始化方法。我做过一个内部工具就是把网络库初始化放到了ContentProvider里效果确实好但要注意权限控制。Provider跑在应用主进程里如果有人拿着debug包直接adb命令去调你的Provider接口是可以绕过业务层读写底层数据的所以authorities和权限别乱给。四大组件一句话总结可以看这张表组件职责交互中心常见宿命Activity界面展示与交互AMS生命周期混乱、进程被回收Service后台任务执行AMS后台限制、前台服务政策BroadcastReceiver事件广播接收AMS注册泄漏、隐式广播受限ContentProvider跨进程数据共享AMS/PackageManager初始化时机隐晦、权限泄露2. AMS与WMS幕后老板分别管什么2.1 AMS管状态、管进程、管任务一座中央调度中心AMS跑在system_server进程里是整个Android应用体系的大脑。它要管的事情极其庞杂但你只需要抓住几条主线。第一管组件状态。每个Activity、Service、Receiver在AMS里都对应一套内部记录比如ActivityRecord、ServiceRecord。系统会跟踪它们处在什么状态、属于哪个进程、跟前台用户有没有关系。前台组件是系统眼中的“香饽饽”进程优先级最高后台不可见且没有Service的进程就是优先回收的对象。第二管任务栈。Activity的启动模式、TaskAffinity、FLAG_ACTIVITY_NEW_TASK这些属性最终都是AMS来解析执行的。你按下Home键再点桌面图标为什么能直接回到原来的界面而不是重新创建因为AMS里的任务列表记住了你那个Task。第三管进程调度。四大组件是系统判断进程优先级的依据。AMS会维护一个ProcessRecord里面记录这个进程都住了哪些组件、当前处于什么状态。内存吃紧的时候系统会按照“最近最少使用”规则杀掉一批后台进程它优先杀的往往就是那些只有空Activity、没有Service、没有前台感知的进程。AMS内部的数据结构可以用现实的“公司后台系统”来类比ActivityRecord像员工档案TaskRecord像项目组ActivityStack像部门ProcessRecord像办公场地。后来Android 10以后ActivityTaskManagerService从AMS里拆了出去专门负责Activity和任务栈的管理AMS本人则继续管进程、Service和广播。作为开发者你不需要背那么多名词只需要有一个大概认知这一家子服务统称“系统服务中的Activity家族”它们共同决定组件怎么流转。2.2 WMS管窗口、管焦点、管布局屏幕上的总导演WMS和AMS是两兄弟AMS管“组件怎么活”WMS管“窗口怎么摆”。组件最终要在屏幕上变成像素靠的就是WMS。你在Activity里setContentView之后真正要向系统登记一个窗口的时刻发生在Activity启动的后半段。具体来说ViewRootImpl会通过WindowSession向WMS发起addWindow请求WMS内部生成一个WindowState对象把它挂到窗口列表里然后和SurfaceFlinger协作完成Surface的分配与合成。WMS干的事包括但不限于维护Z轴顺序哪个窗口在最上面、分配焦点触摸事件给谁、处理动画和转场、协调输入法窗口、处理屏幕旋转后的布局重新计算。如果你的App出现触摸事件莫名不响应、键盘弹出时布局被顶乱、多个窗口之间叠加错乱十有八九都要回到WMS层面去排查。很多人会把WMS和SurfaceFlinger搞混。简单区分一下WMS管理的是窗口层的逻辑属性比如大小、位置、可见性SurfaceFlinger管理的是图层合成真正把各个Surface混成最终一帧画面的活儿是它干的。WMS是导演SurfaceFlinger是剪辑师。2.3 Binder IPC老板和打工仔之间的“专用电话线”四大组件和AMS/WMS之间怎么传话全靠Binder IPC。Binder是Android系统里最核心的跨进程通信机制它比传统的共享内存和Socket更适合这种高频、小数据量、强绑定的调用场景。一个Binder调用大概长这样调用方通过代理对象调用方法方法调用被封装成事务数据写入内核态的Binder缓冲区然后目标进程从自己的线程池里挑一个Binder线程来处理请求最后把结果返回。对开发者的影响主要有两点。第一Binder调用是同步的。你调一个跨进程方法当前线程会卡住等待结果返回所以不要在Binder线程里做耗时操作也不要主线程大批量进行Binder调用。第二Binder传输的数据量有限制。系统里一次事务的可用Buffer通常在1MB上下超过就会抛TransactionTooLargeException。常见就是把一大堆Bitmap数据塞进Intent或者Bundle里准备传给人结果直接把Binder堵死。四大组件启动的过程本质就是通过Binder这条“专用电话线”向AMS和WMS这两个老板汇报需求、等待指示的过程。3. 打工仔见老板组件启动与绑定全链路3.1 Activity启动的九曲十八弯Activity启动链路是所有Android开发者都应该刻在脑子里的主干道。以常规的startActivity为例完整过程大概是这样第一步应用进程通过ActivityManager代理发起startActivity请求参数包括Intent、调用者身份、目标进程等经由Binder传到AMS所在进程。第二步AMS收到请求后先解析Intent确定目标组件。如果Intent没有显式指定组件名系统会基于IntentFilter做匹配这个过程要去PackageManager查清单所以Intent里的Action、Category、Data都得对得上不然就找不到目标。第三步AMS开始做事前检查。比如当前调用进程有没有权限App是不是处于后台启动限制状态待启动的Activity是不是单例模式需要复用已有实例。第四步如果目标Activity所在进程还没起来AMS会先要求创建进程。这里有个关键点App进程创建并不是AMS自己动手而是通过Zygote进程fork出来的。进程创建完成后ActivityThread的main方法跑起来主线程消息循环开始运转。第五步AMS通过ApplicationThread这个内部Binder接口通知应用进程去创建Activity。应用进程这边由ActivityThread接收到消息后用反射创建Activity对象然后依次调用attach、onCreate、onStart、onResume等生命周期方法。第六步Activity创建过程中会调用WindowManager添加窗口。这就要经过刚才说过的addWindow流程WMS给窗口分配WindowState最终和SurfaceFlinger协作让内容上屏。所以你看一次简单的startActivity至少跨越了应用进程和系统进程两道关卡。理解了这个链路你才能明白为什么在onCreate里做重活会让启动白屏变长、为什么进程被杀后恢复Activity要走onCreate而不是onNewIntent、为什么某些Flag会导致完全不同的复用行为。我在实际项目里就吃过TaskAffinity的亏。某个模块为了让Activity复用随便配了taskAffinity结果点击通知拉起页面时系统按着TaskAffinity和LaunchMode的组合规则把Activity开到了一个新任务里用户点返回直接跳回桌面而不是回到App首页。排查时对着dumpsys activity activities输出看了半天才明白是根因。3.2 Service的启动与绑定两条路各有脾气Service启动和绑定是截然不同的两条链路。先用startService举例。应用进程把请求发给AMS后AMS先检查Service是否已经存在不存在就先创建ServiceRecord然后判断Service所在进程是否存活。如果进程没有系统会先创建进程、初始化Application再把Service实例加载起来走onCreate、onStartCommand。这里有个隐藏细节Service的onStartCommand是在主线程执行的所以如果它在里面做网络请求或大文件读写一样会导致ANR。系统对Service的ANR判定标准通常比输入事件更宽松但主线程卡死最终还是要吃“Application Not Responding”。bindService的链路里则多一个连接对象——ServiceConnection。应用进程发请求给AMS后AMS会找到或创建目标Service并且建立一条“绑定”关系。之后AMS返回一个Binder对象给应用进程你在ServiceConnection.onServiceConnected里拿到的就是这个Binder的代理通过它可以直接调用Service内部的方法。绑定关系还会影响进程优先级。被绑定的Service所在进程会随着绑定方的状态上下浮动。如果绑定方是前台Activity那么Service进程就比较安全如果绑定方是后台空壳进程那Service进程也可能被连坐清理。这就是Android系统里“抱团取暖”的优先级策略。实际开发中我遇到过最莫名其妙的Service问题是Service明明在跑却拿不到Context去弹对话框。原因很简单Android 10以后后台弹窗被系统拦截了直接startActivity是弹不出来的不是Service出问题是出头的窗口被WMS按住不许显示。这类问题新手往往百思不得其解。3.3 广播投递系统的一次全城广播广播和Activity、Service最大的区别在于它的投递是“一对多”的。你发一条sendBroadcast系统会去统计所有匹配的Receiver然后依次投递。按发送方式分广播分为普通广播、有序广播和本地广播。普通广播发出后所有Receiver都在同一优先级层次下随机收到有序广播则会按优先级从高到低逐个投递任何一层都可以截断广播不再往下传。本地广播则是利用系统内部的LocalBroadcastManager新版用LiveData之类的方案不会出应用进程。从AMS的角度看广播的投递流程是这样的应用进程通过Binder把广播请求发给AMSAMS先把广播封装成一个BroadcastRecord放入对应的广播队列。然后AMS在队列中依次取出Receiver检查Receiver所在进程如果进程被杀了或者没起来就先拉起进程或安排下次投递。Receiver执行完后AMS标记该广播完成继续下一个Receiver。千万不要小看广播队列。我见过某个项目在onReceive里执行了几MB的数据库读写直接导致系统广播投递超时最后整个App界面无响应。广播接收者里干三类事最危险开线程又不等结果、访问数据库主线程、跨进程同步网络请求。广播的使命是“传消息”不是“做苦力”。要面向低版本兼容动态注册永远比静态注册灵活。你不想让系统进程收到广播时先帮你拉起一个可能几百兆的应用进程就尽量别在Manifest里给第三方应用留可以调用的广播入口。3.4 ContentProvider初始化时机与调用链路ContentProvider的启动逻辑和前面三个组件不太一样它更像App进程启动时的“前置工程”。当你通过包名启动一个App时AMS在创建进程的过程中会指定一个入口这个入口会触发ActivityThread的handleBindApplication执行到installContentProviders这一步。系统读取Manifest里当前进程注册的所有Provider逐个创建实例接下来才回调Application.onCreate。注意这个顺序和直觉相反Provider先初始化Application后初始化。所以很多组件库选择用ContentProvider来做自动初始化本质上就是利用它比Application更早执行这个时间差。这也是为什么许多第三方SDK的接入文档里写着“无需手动初始化”打开App就能用。从调用链路看ContentProvider本身也是一个Binder服务端每个Provider内部维护一个Transport对象跨进程调用CRUD方法时客户端拿到的其实是ContentResolver返回的影子底层最终是透过Binder调用到Provider进程的Transport。如果Provider进程和应用主进程不在同一个进程看android:process配置跨进程访问的性能消耗会比同进程大很多。我的建议是除非数据确实要跨进程共享否则不要轻易把Provider放在独立进程里省得切换进程Binder调用的开销全部砸在操作延迟上。4. 实战避坑常见的恩怨现场与排查技巧4.1 清单文件没注册研发十分钟排查半小时这大概是Android开发里最经典的“低级错误”了。Manifest忘记注册Activity启动的时候抛ActivityNotFoundExceptionManifest里Service注册了但exported、permission配得不对明明代码觉得没问题系统就是不让你启动Provider的authorities写错了跨进程访问直接报无法找到Provider。这类问题的本质是四大组件的“合法身份”由系统进程统一认证。你代码里创建了类但AMS那本花名册上没有它的名字它就不能上岗。排查办法很简单打开AndroidManifest.xml逐项核对。但要提醒一句如果App里用了子模块或者插件化框架子模块的组件可能在主Manifest里找不到需要在运行时动态添加或利用编译期的Manifest占位。我在项目里还遇到过一种情况Manifest的application标签里写了android:name指向了一个自定义Application类但该类内部try-catch把初始化异常吞了结果Activity能启动但很多资源还没准备好一加载就崩溃。这种问题和组件关系不大但它也说明了一个道理组件能正常启动不代表整个系统状态正常。4.2 在主线程里做耗时操作ANR等你上门四大组件的大量生命周期回调都跑在主线程。如果你在这些回调里做耗时操作系统会启动ANR。常见触发点包括Activity输入事件5秒没处理完、BroadcastReceiver的onReceive超过规定时间没返回、Service生命周期回调超时。ANR的本质是系统服务在等你的响应等得不耐烦了就弹窗或者直接杀进程。你会看到logcat里出现类似“Application Not Responding”的日志SystemServer会根据进程的状态决定下一步。我的排查思路是三步走。第一步看logcat里ANR的触发位置——是input dispatching timed out还是broadcast of Intent timed out。第二步去data/anr目录下找到对应的traces文件看主线程堆栈卡在哪个方法。第三步根据堆栈定位代码该异步的异步、该加锁的加锁。90%的ANR都是主线程在等待一个被占用的锁或锁等待Binder返回而不是真的CPU跑不够。切忌在ANR日志里看到一堆线程在等锁就慌了手脚顺势就去改业务代码。正确姿势是先看主线程等的是哪个对象再顺着对象去找谁持锁不释放往往最终根因是某段同步代码里搞了一个网络请求响应慢还占用着锁。4.3 Binder一次事务1MB数据量大会翻车Binder传输大小限制是很多人都会碰到但又不太理解的坑。最常见的情景就是startActivity时Intent里塞了一张大图或者BroadcastReceiver传递一个几十MB的ArrayList。系统在处理时可能会直接抛TransactionTooLargeException你看到日志一脸懵数据明明不大啊。其实不是数据本身大是Binder驱动准备的共享缓冲区有上限。一次跨进程事务可用的内存Buffer在绝大多数Android设备上就是1MB上下。超过这个量系统不帮你拆分直接拒绝。解决的办法也很朴素不要用Intent或Bundle传大对象改用文件路径、数据库ID、或者内存级缓存。我自己的习惯是Intent里永远只传id或轻量参数真正的数据通过一个短期缓存容器从A页传递到B页。另外要注意不要试图把TransactionTooLargeException当成偶发问题忽略它在低内存设备上出现的概率会更高因为可用Buffer还会被系统压缩。4.4 组件生命周期与进程被杀恢复现场是门手艺进程被系统回收是Android的常态。回收优先级通常是这样前台有Activity的进程最安全正在执行Service的次之有Provider的再次之只有空进程的纯后台App最容易被梭哈。但进程被杀后组件状态并不会完全丢失。系统会在AMS里保留一些关键信息。比如ActivityRecord中记录了原Activity的保存状态你重新启动App时系统会把savedInstanceState原样还给你Service如果被设计成START_REDELIVER_INTENT进程被杀后系统还会拿旧Intent重新拉起它。有次我接到线上反馈说用户从后台切回App时经常白屏一查是因为Activity在onSaveInstanceState里塞了Token信息Token对应的对象却已经被清空恢复时拿到空对象直接崩。这种问题排查起来极其痛苦因为不是每次都复现。解决方案就是尽量不在savedInstanceState里保存强引用类型只保存可序列化的元数据真正的重数据启动后再重新拉取。5. 修车工修炼源码入口与调试方法论5.1 用dumpsys看老板心里的账本当你怀疑系统服务和组件状态不对时最直接的手段就是查dumpsys。它相当于从system_server进程里读取内存状态把AMS、WMS等服务的内部数据结构打印出来。查看Activity任务栈和生命周期状态adb shell dumpsys activity activities查看进程状态和缓存级别adb shell dumpsys activity processes查看窗口列表和焦点归属adb shell dumpsys window windows以dumpsys window windows为例你看输出能看到每个窗口的包名、WindowState、可见性、Focus状态、动画状态。如果触摸事件失灵先确认焦点窗口是不是你的包名如果界面一直盖着一层透明系统窗口就要看是不是有别的App在你之上放了个window。我排查过一个问题App偶尔出现点击无响应用dumpsys window windows一查才发现有个输入法窗口一直在抢焦点原因是某个页面里被动弹出过输入框又没收起。这龌龊问题在代码表现上几乎无迹可寻只有从系统状态下手才能定位。5.2 源码阅读路线从组件到系统服务如果你想看得更深直接翻源码是最扎实的方式。系统服务相关代码在AOSP里的路径大致如下frameworks/base/services/core/java/com/android/server/am/ frameworks/base/services/core/java/com/android/server/wm/ frameworks/base/core/java/android/app/ActivityThread.java frameworks/base/core/java/android/app/Instrumentation.java frameworks/base/core/java/android/os/Binder.java建议阅读顺序先从应用侧开始ActivityThread的handleLaunchActivity方法看起看组件是怎么被创建出来的再去AMS侧看startActivity的实现最后回应用侧看生命周期响应的完整闭环。不要一上来就啃系统服务那样容易陷入细节沼泽。读源码的时候带着问题去读比如“onPause到底是谁调用的”“新Intent是如何决定复用还是新建的”“窗口是什么时候被真正显示出来的”。每解决一个问题你对整套系统的理解就会上一个大台阶。5.3 用日志定位从应用侧到system_server侧排查跨进程问题时光看App日志不够要把视野放到整个system_server。常见的做法是抓取包含ActivityManager、WindowManager标签的日志adb logcat -s ActivityManager:I WindowManager:I这样能看到AMS/WMS层面的关键动作比如组件启动、进程创建、窗口添加、焦点变化。如果嫌系统日志太吵还可以针对某个包名过滤adb logcat --pid$(adb shell pidof com.example.app)还有一种情况App自己日志里完全看不出问题但系统服务的日志里明确写着“Permission Denial”或“Background activity start restriction”。这种日志就是老板在背后给你的警告学会看它排查效率能翻倍。6. 写在最后我的几点体会把这套“四大组件打工仔与AMS-WMS幕后老板”的关系搞明白之后你再去看很多Android问题思路会完全不同。组件只是暴露给开发者的入口真正掌管生杀大权的一直是系统进程里那套服务矩阵。你要做的不是所有代码都自己掌控而是理解这套协作规则懂得什么时候该顺着系统走、什么时候可以利用系统的特性做优化。我个人至今仍然建议每个想进阶的Android开发者至少完完整整看一遍Activity启动流程的源码再配合几次真实的ANR和Binder异常排查。这个过程会很痛苦但收益真的很大。四组件和AMS/WMS之间的关系就像是公司里基层员工和后台管理系统的关系制度不理解透干活永远提心吊胆。把那些“为什么”弄明白写代码时你心里才真正有底。

相关新闻

React待办清单实战:从跑通到拆解状态管理与本地持久化

React待办清单实战:从跑通到拆解状态管理与本地持久化

简介:这是一份面向 React 初学者与前端进阶者的待办事项清单实战项目源码,基于 React.js 构建,配合 Node.js、Webpack 与 SCSS 完成工程化与样式组织,适合用来练习组件拆分、状态管理与列表增删交互。压缩包共 15 个文件&#xff…

2026/10/14 19:58:07 阅读更多 →
MyBatis逆向工程:从数据库Schema到可维护Mapper的工程化实践

MyBatis逆向工程:从数据库Schema到可维护Mapper的工程化实践

1. 项目概述:为什么“MyBatis逆向工程”不是偷懒捷径,而是团队提效的底层基建你有没有经历过这样的场景:一个新数据库表上线,字段12个,关联3张字典表,业务接口要查、要改、要分页、要导出——光是手写Mappe…

2026/10/14 19:58:07 阅读更多 →
真题资源高效利用:从分类索引到三轮刷题法的完整训练指南

真题资源高效利用:从分类索引到三轮刷题法的完整训练指南

简介:这是一份面向蓝桥杯参赛者的历年真题合集,涵盖省赛与国赛两个层级的代表性赛题,适用于正在备赛的本科、高职院校学生及指导老师。资源以rar压缩包形式整体打包,大小约62.1MB,便于一次性获取多届试题并离线使用&am…

2026/10/14 19:58:07 阅读更多 →

最新新闻

yolov8-face 核心算子全解析:NMS、边界框格式转换与掩码处理的源码级指南

yolov8-face 核心算子全解析:NMS、边界框格式转换与掩码处理的源码级指南

人工智能计算机视觉深度学习 【免费下载链接】yolov8-face yolov8 face detection with landmark 项目地址: https://gitcode.com/gh_mirrors/yo/yolov8-face 点击查看 免费下载 本文是 ops.md 参考文档的深度展开,以 ultralytics/yolo/utils/ops.py 为…

2026/10/14 20:49:14 阅读更多 →
自学嵌入式第二天(C语言篇——数据类型)

自学嵌入式第二天(C语言篇——数据类型)

琐碎的敲代码内功。(以为很简单 ,结果全是坑)1.C语言提供的数据类型2.整数类型常量:在程序运行过程中,其值不能被改变的量变量:在程序运行过程中,其值能被改变的量(1)整型…

2026/10/14 20:49:14 阅读更多 →
openJiuwen 记忆引擎基础模型:MemInfo 单条记忆信息结构全解

openJiuwen 记忆引擎基础模型:MemInfo 单条记忆信息结构全解

人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习 【免费下载链接】agent-core-java openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。 项目地址: https://gitco…

2026/10/14 20:49:14 阅读更多 →
模拟退火求解二维装箱问题:原理、实现与工程调优

模拟退火求解二维装箱问题:原理、实现与工程调优

模拟退火算法求解装箱问题,我第一次真正上手,是在一个托盘排样项目里。需求方只说了一句话:把尺寸不一的纸箱尽量多地放进托盘,允许90度旋转,不许压坏。我当时觉得,这就是矩形排样,先求个面积下…

2026/10/14 20:49:14 阅读更多 →
51单片机DHT11温湿度采集实战:从仿真到实物的完整拆解

51单片机DHT11温湿度采集实战:从仿真到实物的完整拆解

简介:一套以51单片机为核心的温湿度采集监控完整工程,面向电子爱好者、嵌入式初学者及课程设计学生。资料基于Keil平台,由C语言编写,实现温湿度采集(SHT10传感器)、日历时钟(DS1302)…

2026/10/14 20:49:14 阅读更多 →
Towards Automated Regulatory Compliance Verification in Financial Auditing with Large Language Mo...

Towards Automated Regulatory Compliance Verification in Financial Auditing with Large Language Mo...

文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现财务审计中监管合规性的自动验证,旨在解决传统审计中人工验证合规性的低效问题。研究对比了开源LLMs(如Llama-2系列)与专有LLMs(如OpenAI的GPT系列)在合规性检测中的性能,使用了普华永道(PwC)提供的两个自定义…

2026/10/14 20:48:13 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →