Unity GC优化入门:从原理到实战,解决移动端卡顿问题
1. 项目概述为什么Unity GC优化是初学者的必修课如果你刚开始接触Unity开发可能觉得游戏能跑起来、画面看起来不错就万事大吉了。但当你第一次尝试在手机上打包运行一个稍微复杂点的场景或者看着编辑器里那个代表内存的绿色柱状图不断攀升、最终游戏卡顿甚至闪退时你大概率会第一次直面“垃圾回收”这个拦路虎。尤其是在移动端性能预算极其有限一次不合时宜的GCGarbage Collection垃圾回收卡顿足以毁掉玩家的游戏体验。网络上搜索“Unity 性能优化”、“移动端性能优化”GC永远是绕不开的核心话题甚至成了面试中的“八股文”考点这恰恰说明了它的普遍性和重要性。对于初学者而言GC优化听起来可能很底层、很复杂涉及内存管理和运行时原理。但实际上它的核心思想非常直接减少不必要的内存分配从而减少GC触发次数和每次GC的工作量最终让游戏运行得更流畅。本篇文章的目的就是剥开GC神秘的外衣用最直白的语言和可立即上手的实践带你理解Unity中GC的工作原理、它为何会导致卡顿以及作为一名初学者你可以立即采取的、最有效的优化策略。我们不会深究Mono或IL2CPP后端的实现差异而是聚焦于那些你写代码时就能注意到的、立竿见影的优化习惯。2. GC基础Unity中的垃圾回收是如何工作的在深入优化之前我们必须先理解“敌人”是如何运作的。Unity主要使用基于Boehm GC算法的Mono运行时或IL2CPP转换后的原生代码管理内存其GC过程可以简单理解为“标记-清扫”。2.1 核心概念托管堆、引用与垃圾想象一下你的游戏世界是一个大仓库托管堆。当你写new Enemy()或string.Format(“Player: {0}”, score)时你就是在仓库里申请一个货架并把东西对象实例放上去。Unity会跟踪哪些货架上的东西还在被使用即存在有效的引用指向它比如你的GameObject组件还持有一个Enemy脚本实例的引用。当某个对象没有任何活跃的引用指向它时例如一个临时创建的Vector3计算完后就没人再用了或者一个被销毁的GameObject上的组件它就变成了“垃圾”。但请注意垃圾并不会被立即清理。它只是占着货架标记为可回收。2.2 GC的触发时机被动与主动GC不会每时每刻都在打扫仓库那样开销太大。它主要在两种情况下启动被动触发自动这是最常见的情况。当Unity运行时发现托管堆上分配的内存达到某个阈值或者经过一定时间后为了预防内存不足它会自动启动一次GC。这个阈值是动态的但总体趋势是你分配得越快、越多GC就被触发得越频繁。主动触发手动你可以通过调用System.GC.Collect()来强制进行垃圾回收。但初学者请务必谨慎使用在不合适的时机如游戏关键帧手动调用GC很可能导致一次明显的卡顿弊大于利。通常只在加载场景的过渡期、暂停菜单等对帧率不敏感的时刻考虑使用。2.3 GC的工作流程与“卡顿”根源一次完整的GC主要包含两个阶段标记阶段GC暂停所有托管代码的执行这就是卡顿的直接原因遍历所有已知的“根”对象如静态变量、当前执行栈上的局部变量等并递归标记所有能从“根”访问到的对象为“存活”。这个过程需要时间对象引用关系越复杂耗时越长。清扫与压缩阶段将所有未被标记的对象即垃圾占用的内存回收。在某些情况下GC还会尝试移动存活的对象将它们紧密排列压缩以腾出更大的连续空闲内存块但这会带来额外的开销。关键点GC的“世界暂停”特性是性能问题的元凶。你的游戏帧率可能是60FPS即每帧只有约16.7毫秒的预算。一旦GC工作超过这个时间比如花了50毫秒玩家就会感觉到明显的掉帧或卡顿。因此优化的核心目标就是减少GC的频率和每次GC的持续时间。注意这里提到的GC主要指托管代码的垃圾回收。Unity项目中还可能涉及Lua如XLua、ToLua的内存管理、原生插件分配的内存等这些都有各自的GC或管理机制需要分别处理。本文聚焦于最普遍的C#托管内存GC。3. 初学者最常踩的GC陷阱与优化策略理解了原理我们就可以针对性地行动。以下是一些对初学者效果最显著、最容易犯错的点及其优化方案。3.1 陷阱一在频繁调用的函数中分配堆内存这是GC问题最主要的来源。任何new关键字用于引用类型、装箱操作、字符串拼接等都会在托管堆上分配内存。高频重灾区Update()、FixedUpdate()、LateUpdate()中的临时对象创建。每帧执行的协程Coroutine中的分配。物理碰撞、触发事件回调函数中的分配。优化策略1对象池Object Pooling对于需要频繁创建和销毁的物体如子弹、敌人、特效粒子绝对不要每用一次就Instantiate不用了就Destroy。这两个操作开销巨大且会产生垃圾。实操示例一个简单的游戏对象池using System.Collections.Generic; using UnityEngine; public class SimpleObjectPool : MonoBehaviour { public GameObject prefab; public int initialSize 10; private QueueGameObject objectPool new QueueGameObject(); void Start() { for (int i 0; i initialSize; i) { CreateNewObject(); } } private GameObject CreateNewObject() { GameObject obj Instantiate(prefab); obj.SetActive(false); // 初始设为不可用 obj.transform.SetParent(this.transform); // 统一管理 objectPool.Enqueue(obj); return obj; } public GameObject GetObject() { if (objectPool.Count 0) { CreateNewObject(); } GameObject obj objectPool.Dequeue(); obj.SetActive(true); return obj; } public void ReturnObject(GameObject obj) { obj.SetActive(false); objectPool.Enqueue(obj); } }使用方式在需要子弹时调用pool.GetObject()并从池中取一个子弹命中或超出边界后调用pool.ReturnObject(bullet)将其还回池中而不是Destroy。这样整个游戏过程中可能只初始创建了20个子弹对象循环使用完全避免了运行时分配和GC。优化策略2避免在循环或高频函数中使用返回新数组/列表的方法例如GetComponentsT()、Physics.OverlapSphere等。它们每次调用都会返回一个新的数组。如果每帧都需要调用GC压力会很大。优化方案使用非分配版本Alloc-free或缓存结果。// 不推荐每帧分配新数组 void Update() { Collider[] hits Physics.OverlapSphere(transform.position, radius); // ... 使用 hits // 函数结束hits数组成为垃圾 } // 推荐使用预分配的数组或列表 private Collider[] overlapResults new Collider[10]; // 根据预估的最大数量初始化 void Update() { int numHits Physics.OverlapSphereNonAlloc(transform.position, radius, overlapResults); for (int i 0; i numHits; i) { // 处理 overlapResults[i] } // 没有新数组分配 }Unity的Physics、GetComponents等很多API都提供了NonAlloc或带缓存列表的重载版本务必优先使用。3.2 陷阱二字符串操作产生的GC字符串在C#中是不可变的immutable。任何修改字符串的操作如拼接、String.Format、String.Replace实际上都会创建一个全新的字符串对象丢弃旧的从而产生垃圾。坏例子void UpdateScoreDisplay(int score) { // 每次调用都产生新的字符串垃圾 text.text Score: score; }优化方案使用StringBuilder进行复杂的字符串构建特别是循环拼接时。StringBuilder sb new StringBuilder(); sb.Append(Player: ); sb.Append(playerName); sb.Append( | Score: ); sb.Append(score); text.text sb.ToString(); // 仅在此处分配一次 // 可以清空StringBuilder后重用sb.Length 0; sb.Capacity 0;对于简单的UI文本更新考虑预格式化private string scorePrefix Score: ; void UpdateScoreDisplay(int score) { // 仍然有分配但比拼接两个部分稍好。对于高频更新仍有优化空间。 text.text scorePrefix score; }使用TextMeshPro对于UGUITextMeshPro的SetText方法有重载支持字符串格式化且GC分配更低是更好的选择。3.3 陷阱三装箱Boxing操作装箱是指将值类型如int,float,struct转换为object引用类型或接口类型的过程。这个过程会在堆上分配内存。常见的隐蔽装箱场景将值类型添加到ArrayList已过时但需注意或作为object类型参数传递。在非泛型集合中使用值类型如Hashtable。对值类型调用ToString()、GetType()等继承自object的方法本身不会装箱但若将值类型转换为IFormattable等接口可能会。优化方案始终使用泛型集合Listint、Dictionarystring, Vector3等。它们避免了装箱拆箱。注意方法签名确保委托和接口方法使用泛型参数避免值类型被当作object传递。3.4 陷阱四闭包与匿名方法在C#中Lambda表达式和匿名方法如果捕获了外部变量编译器会生成一个隐藏的类来存储这些变量这会导致堆分配。例子void Start() { int localCounter 0; // 这个Lambda捕获了localCounter会导致堆分配 someButton.onClick.AddListener(() { localCounter; Debug.Log(localCounter); }); }虽然一次按钮监听的分配可以接受但如果是在Update中频繁定义这样的委托问题就严重了。优化方案对于高频调用的委托如每帧执行的Action尽量使用预先定义好的方法而不是临时的Lambda。如果必须使用Lambda且关心性能可以考虑将捕获的变量提升为类的成员变量从而避免闭包生成。4. 实战使用Profiler工具定位并分析GC问题理论说再多不如实战看一眼。Unity Profiler是你进行GC优化的最强武器。4.1 打开Profiler并定位GC分配菜单栏Window Analysis Profiler打开窗口。运行你的游戏。在Profiler窗口顶部选择“CPU Usage”模块。在CPU时间线下方找到“GC Alloc”列并确保它被勾选显示。这一列直观地显示了每一帧在托管堆上分配的内存量。观察时间线你会看到许多代表GC分配的彩色柱状图通常是淡绿色。我们的目标就是让这些柱子尽可能矮甚至没有。4.2 深度分析使用Deep Profile和Hierarchy视图看到GC分配后我们需要知道是哪行代码分配的。在Profiler中点击“Deep Profile”按钮注意这会极大增加性能开销可能导致游戏变慢仅用于短时间诊断。或者对于更高效的分析使用“Hierarchy”视图并确保捕获调用堆栈。在CPU使用详情面板选择一帧GC分配很高的帧。在下方详情视图中切换到“Hierarchy”模式。找到“GC Alloc”列点击进行排序排在最上面的就是该帧分配内存最多的函数。展开该函数你可以看到完整的调用堆栈。点击堆栈中的任意条目Unity编辑器会自动跳转到对应的代码行如果拥有脚本符号。典型分析案例 你可能会发现最大的分配来自一个名为UpdateScoreText的函数调用堆栈显示分配发生在String.Concat上。这就印证了我们之前提到的字符串问题。或者你可能发现分配来自Instantiate这就指向了对象池的使用需求。4.3 使用Memory Profiler进行更精细的内存快照对于更复杂的内存泄漏问题即对象本应被回收却一直存活可以使用Memory Profiler包通过Package Manager安装。它可以拍摄两个时间点的内存快照Snapshot。对比两个快照可以精确地看到哪些类型的对象增加了以及是什么引用路径保持这些对象存活防止被GC。这对于查找由于静态引用、事件监听未取消注册等原因造成的内存泄漏非常有效。实操心得不要试图一次性消除所有GC分配。优先处理那些每帧都在发生的、分配量大的“持续性”分配。对于只在场景加载、初始化时发生的一次性大分配可以适当放宽要求。优化是一个持续的过程。5. 进阶技巧与架构层面的考量当你掌握了基础优化后可以进一步从代码架构上减少GC压力。5.1 结构体struct的合理使用值类型struct分配在栈上或作为引用类型的一部分内联分配当它们超出作用域时会被自动清理不经过GC。但切勿滥用。适合使用struct的情况小型、不可变的数据集合如Vector3,Quaternion,Color32。用于高频计算的临时数据例如自定义的Ray、Bounds结构。当它逻辑上代表一个单一的值且实例大小小于约16字节时因为传递大的结构体会产生复制开销。不适合使用struct的情况需要继承或多态。数据规模较大。需要频繁作为参数传递可能产生复制开销。需要表示“不存在”的状态struct不能为null需使用NullableT。5.2 缓存组件与引用使用GetComponentT()、Find、FindObjectOfType等方法是有成本的。虽然它们不直接产生托管堆垃圾Find方法可能产生但CPU开销也不小。最佳实践是在Awake()或Start()中获取并缓存引用。private Rigidbody rb; private Animator animator; void Awake() { rb GetComponentRigidbody(); animator GetComponentInChildrenAnimator(); // 避免在Update中频繁调用GetComponent } void Update() { // 直接使用缓存的rb和animator velocity rb.velocity; }5.3 警惕事件与委托的泄漏未正确注销的事件监听是内存泄漏的常见原因会导致对象无法被GC回收。void OnEnable() { GameManager.OnPlayerDied HandlePlayerDied; } void OnDisable() { // 务必配对注销否则即使GameObject被销毁本脚本实例仍被GameManager引用。 GameManager.OnPlayerDied - HandlePlayerDied; }对于UI按钮的监听在Unity中如果监听目标如你的MonoBehaviour脚本所在的GameObject被销毁Unity会自动清理引用。但为了代码清晰和跨平台一致性手动在OnDestroy中移除监听是好习惯。6. 常见问题排查与性能陷阱实录即使遵循了所有建议你可能还是会遇到棘手的GC问题。以下是一些常见场景和排查思路。问题1我用了对象池但Profiler显示Object.Instantiate调用依然很多。排查检查对象池的初始大小是否足够。如果池中对象用尽你的GetObject()方法会调用Instantiate来扩容。适当增加initialSize或实现一个动态扩容策略如每次扩容翻倍减少扩容频率。问题2字符串操作已经用了StringBuilder但UI文本更新仍有GC。排查Text/TextMeshPro组件在设置text属性时Unity底层可能会进行一些处理。确保你没有每帧都设置相同的文本可以先判断值是否变化。对于TextMeshPro使用SetText的重载如SetText(“Score: {0}”, score)其GC效率通常比先构建字符串再赋值更高。问题3在协程Coroutine中使用了yield return new WaitForSeconds()这会产生GC吗回答会的。每次new WaitForSeconds都会在堆上分配一个小对象。对于高频使用的、固定间隔的等待可以缓存这个等待对象。private WaitForSeconds waitOneSecond new WaitForSeconds(1f); IEnumerator MyCoroutine() { while(true) { yield return waitOneSecond; // 复用同一个对象无分配 DoSomething(); } }同理适用于WaitForEndOfFrame,WaitForFixedUpdate。但注意yield return null不会分配。问题4foreach循环比for循环产生更多GC吗回答对于使用泛型集合如ListT在Unity旧版本约2018.3之前的Mono运行时foreach可能会为迭代器分配少量内存。但在较新版本和IL2CPP后端下这个差异通常已被优化掉。从代码清晰度出发可以优先使用foreach。如果是在极度性能敏感的代码段如每帧处理上千个元素的循环并且用Profiler证实了这里有分配可以改为for循环进行对比测试。问题5使用了LINQ和Lambda表达式GC很高怎么办回答LINQ如.Where(),.Select(),.First()虽然写起来简洁但会产生大量的中间委托对象和迭代器对象GC开销很大。在性能关键路径如Update, 频繁调用的函数中应避免使用LINQ。用传统的for/foreach循环手动实现同样的逻辑。优化GC是一个从意识到习惯的过程。最开始你需要主动使用Profiler去“狩猎”分配热点。久而久之当你写下new、字符串或者准备调用一个可能返回新数组的API时你会自然而然地停顿一下思考“这里是否在频繁调用有没有更高效的方式”。这种思维习惯才是从初学者迈向成熟开发者的关键一步。记住没有绝对的“零GC”我们的目标是在有限的性能预算内将GC的影响降到玩家无法感知的程度。

相关新闻

C++ RAII编程范式:资源自动管理、异常安全与工程实践

C++ RAII编程范式:资源自动管理、异常安全与工程实践

1. 项目概述:为什么RAII是C程序员的必修课 如果你写过C,大概率遇到过内存泄漏、文件句柄未关闭或者互斥锁忘记解锁的“惊喜”。这些资源管理上的失误,轻则导致程序内存占用缓慢增长,重则直接引发程序崩溃或死锁,尤其是…

2026/8/11 14:56:35 阅读更多 →
开源AI编程助手实战:基于Ollama与Qwen2.5-Coder搭建本地代码生成服务

开源AI编程助手实战:基于Ollama与Qwen2.5-Coder搭建本地代码生成服务

最近在AI圈子里,一个趋势越来越明显:无论是OpenAI还是Anthropic,都在不约而同地加大投入,争夺一个看似传统但潜力巨大的市场——AI编程助手。从OpenAI Codex的推出,到Claude Code的迭代,再到最近关于OpenAI…

2026/8/11 14:56:35 阅读更多 →
Mac本地离线AI编码助手搭建指南:基于Ollama与VS Code

Mac本地离线AI编码助手搭建指南:基于Ollama与VS Code

在 Mac 上构建一个完全本地、离线的编码智能体,是许多开发者追求的目标。这不仅能保护代码隐私、避免网络延迟,还能在无网或弱网环境下保持高效工作。Magnitude 正是这样一个概念,它代表了一种将大型语言模型(LLM)的代…

2026/8/11 14:56:35 阅读更多 →

最新新闻

昆明燃气灶维修全域覆盖 欧米到家同城上门深度检修承诺不返工|打不着火|松手熄火|黄火冒黑烟|漏气|各类故障一站式解决

昆明燃气灶维修全域覆盖 欧米到家同城上门深度检修承诺不返工|打不着火|松手熄火|黄火冒黑烟|漏气|各类故障一站式解决

导读昆明燃气灶出现打不着火、点火后松手熄火、火焰发黄、冒黑烟、燃烧不均、旋钮失灵或疑似漏气等问题,可联系欧米到家统一报修热线400-996-9791。平台根据所在区域安排同城维修师傅上门,先检测故障原因,再说明维修方案和费用,确…

2026/8/11 15:38:52 阅读更多 →
CanguoAI马上解决文献地图,不是“炫酷关系图”:它应该帮你决定下一篇读什么

CanguoAI马上解决文献地图,不是“炫酷关系图”:它应该帮你决定下一篇读什么

当论文从 20 篇增长到 200 篇,真正稀缺的不是搜索结果,而是一条能解释研究结构、安排精读顺序的导航路径。图 1:文献地图的价值不在于画出多少节点,而在于识别主题簇、桥接论文和可继续追问的研究路径。 导语:文献太多…

2026/8/11 15:38:52 阅读更多 →
别再瞎按了!Python键盘输入三招,一招比一招狠

别再瞎按了!Python键盘输入三招,一招比一招狠

通过多种方式能够获得键盘输入, 其中最为常用的涵盖: 应用input()函数, 运用sys.stdin, 借助第三方库来实施捕获。这些方法各自具备适用场景以及优缺点。本文会详细介绍这些方法, 并且探讨它们在不同应用里的最佳使用实践。一、使用input()函数获取用户输入的最为简单、也最为常…

2026/8/11 15:38:52 阅读更多 →
BG3ModManager完全指南:3步解决《博德之门3》模组管理难题

BG3ModManager完全指南:3步解决《博德之门3》模组管理难题

BG3ModManager完全指南:3步解决《博德之门3》模组管理难题 【免费下载链接】BG3ModManager A mod manager for Baldurs Gate 3. This is the only official source! 项目地址: https://gitcode.com/gh_mirrors/bg/BG3ModManager BG3ModManager是《博德之门3》…

2026/8/11 15:38:52 阅读更多 →
电商首页加速方案详解:预渲染 + CDN、ISR、CSR 与边缘 SSR 全对比

电商首页加速方案详解:预渲染 + CDN、ISR、CSR 与边缘 SSR 全对比

电商首页加速方案详解:预渲染 + CDN、ISR、CSR 与边缘 SSR 全对比 适合人群:前端、Node、运维、架构同学 技术栈关键词:Vue3 SSR / Nuxt / Next.js / S3 / CloudFront / Nginx / ISR / Edge 前言 电商商城首页往往是整站 QPS 最高、转化最敏感的入口之一。首页慢,不只是「…

2026/8/11 15:38:51 阅读更多 →
5分钟快速上手:ExplorerPatcher让Windows 11回归经典界面体验

5分钟快速上手:ExplorerPatcher让Windows 11回归经典界面体验

5分钟快速上手:ExplorerPatcher让Windows 11回归经典界面体验 【免费下载链接】ExplorerPatcher This project aims to enhance the working environment on Windows 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher 还在为Windows 11的新…

2026/8/11 15:37:51 阅读更多 →

日新闻

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/v…

2026/8/11 0:00:02 阅读更多 →
前后端分离项目中控制台与接口工具数据差异排查指南

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析:控制台与Apifox的数据差异 最近在调试一个前后端分离项目时,遇到了一个典型问题:后端服务在本地开发环境控制台能正常输出查询数据,但通过Apifox测试时却返回空结果。这种"控制台有数据,接口工具…

2026/8/11 0:00:03 阅读更多 →
AI编程实战:从Claude Code踩坑到游戏开发入门

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友,尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友,都在问我同一个问题:“听说现在用Claude Code这种AI编程工具,小白也能做游戏了,是真的吗&#…

2026/8/11 0:00:03 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/11 1:08:05 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 1:08:05 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/11 1:08:05 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/10 17:07:33 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/11 1:08:06 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/10 17:07:33 阅读更多 →