Android singleTask启动模式深度解析:从原理到实战避坑指南
1. 项目概述为什么我们需要深入理解singleTask在Android开发中Activity的启动模式是一个老生常谈却又常谈常新的基础话题。尤其是singleTask模式它不像standard或singleTop那样直观其行为与Task任务栈的概念深度绑定理解稍有偏差就容易在复杂的页面跳转逻辑中埋下难以排查的“坑”。我见过不少项目因为对singleTask的误用导致了页面重复创建、数据状态混乱甚至出现诡异的“回退到桌面”的体验。这不仅仅是记住“一个Task里只有一个实例”这么简单其背后的栈管理机制、Intent的传递、onNewIntent的调用时机以及与launchMode、Intent标志位如FLAG_ACTIVITY_NEW_TASK的交互共同构成了一个精密的系统。今天我们就抛开那些笼统的定义从一个一线开发者的视角结合实际的代码和场景把singleTask里里外外彻底拆解清楚。2. singleTask的核心机制与设计初衷2.1 Task任务栈的再认识要理解singleTask必须先吃透Task。你可以把Task想象成一个存放Activity实例的“容器”或“栈”。用户感知到的一个“应用”在后台可能由一个或多个Task构成。每个Task都有自己的回退栈Back Stack遵循后进先出LIFO原则。关键在于Task并不严格等同于一个应用进程。一个应用一个APK可以创建多个Task而一个Task也可以容纳来自不同应用的Activity在权限允许的情况下。系统Launcher、最近任务列表Recents展示的基本单位就是Task。singleTask模式的核心作用域就是这个Task。2.2 singleTask的官方定义与行为拆解官方文档对singleTask的描述是系统在一个新的Task的根位置创建Activity并且该Activity是该Task中唯一的Activity。然而如果该Activity的实例已经存在于一个独立的Task中系统会通过调用其onNewIntent()方法将Intent路由到该现有实例而不是创建新实例。这个定义里有几个关键点我们逐一拆解“新的Task的根位置”这意味着当系统需要为这个singleTaskActivity创建一个新实例时它会同时或者说优先为其分配一个全新的、独立的Task并将这个Activity作为该Task的根Activity即栈底Activity。“该Task中唯一的Activity”这是一种理想化的描述。更准确的说法是系统会确保在整个系统中该singleTaskActivity的实例在它所属的那个Task里是唯一的。但这个Task里完全可以有它之上的其他Activity。“已经存在于一个独立的Task中”这是singleTask复用逻辑的触发条件。系统会遍历所有已存在的Task寻找目标singleTaskActivity的实例。找到后就会将整个Task带到前台并清理掉该实例之上的所有Activity如果需要最后将Intent传递给该实例。2.3 与singleInstance的微妙区别很多人容易混淆singleTask和singleInstance。简单来说singleTask它所在的Task可以容纳其他Activity。例如一个singleTask的MainActivity在栈底用户可以从它跳转到DetailActivity这个DetailActivity就会进入同一个Task并位于MainActivity之上。singleInstance它所在的Task只能有它自己一个Activity。如果它需要启动另一个Activity系统会强制为那个新Activity创建一个新的Task。这更像是一个“孤岛”模式通常用于需要绝对独立、避免被其他Activity干扰的场景如来电接听界面。所以singleTask更常见于我们希望作为某个功能流程的“唯一入口”或“重新归位点”的Activity例如应用的主页、登录页、支付收银台等。3. singleTask的启动流程与栈变化实战理论说再多不如看代码和日志来得实在。我们通过一个经典的A-B-C-D页面跳转场景来演示。假设我们有四个ActivityA(standard),B(standard),C(singleTask),D(standard)。 初始栈状态Task 1: [A](A是根当前显示A)场景1从A启动B (standard)操作在A中startActivity(new Intent(this, B.class))栈变化Task 1: [A - B]行为标准启动B入栈显示B。场景2从B启动C (singleTask)操作在B中startActivity(new Intent(this, C.class))关键点C被声明为singleTask。此时系统中没有C的实例。栈变化系统会为C创建一个新的Task假设为Task 2并将C作为根放入。Task 2: [C]。同时系统会将Task 2带到前台。当前显示C。此时回退栈Recents里可以看到两个任务。日志C会经历完整的生命周期onCreate()-onStart()-onResume()。场景3从C启动D (standard)操作在C中startActivity(new Intent(this, D.class))栈变化因为D是standard且当前前台任务是C所在的Task 2所以D会被压入Task 2的栈。Task 2: [C - D]。行为这证明了singleTask的Task里是可以有其他Activity的。场景4再次从A或其他任何地方启动C (singleTask)这是singleTask最核心的复用逻辑。操作例如在D中我们通过一个通知或Deep Link再次启动CstartActivity(new Intent(this, C.class))。关键点系统发现C的实例已经存在于Task 2中。栈变化系统找到Task 2。将Task 2带到前台。因为目标实例C已经在栈中系统会清理掉C之上的所有Activity即D使得C成为栈顶。Task 2: [C](D被销毁)。C不会重新创建而是会收到onNewIntent(Intent)回调然后经历onRestart()-onStart()-onResume()。当前显示C。用户感觉像是从D“返回”到了C但实际上D被销毁了。日志C的onNewIntent()被调用onDestroy()和onCreate()不会被调用。注意这里的“清理”行为是默认的由Intent的标志位或Activity的android:launchMode属性决定。singleTaskActivity在收到新Intent并成为前台时其taskAffinity指定的Task中位于它之上的所有Activity都会被移除destroy。这是实现“回到起点”效果的关键。3.1 taskAffinity属性指定singleTask的“家”android:taskAffinity是一个常被忽略但至关重要的属性。它像一个“地址”告诉系统这个Activity“希望”住在哪个Task里。默认情况下一个应用内所有Activity的taskAffinity都相同包名。对于singleTaskActivity系统会寻找与其taskAffinity匹配的Task。如果找到就复用该Task中的实例如果没找到就创建一个具有该taskAffinity的新Task。示例activity android:name.PaymentActivity android:launchModesingleTask android:taskAffinitycom.example.app.payment /这样PaymentActivity就会寻找或创建affinity为com.example.app.payment的Task与应用主Taskaffinity为包名隔离开。这在组织不同功能模块时非常有用。4. onNewIntent()的正确处理与数据传递当singleTaskActivity被复用并带到前台时onNewIntent(Intent)是接收新数据的唯一入口。这里有很多细节需要注意。4.1 onNewIntent的调用时机与生命周期onNewIntent()的调用发生在onRestart()之后onStart()之前。但更重要的顺序是先调用onNewIntent()再调用onResume()。这意味着在onResume()中你已经可以访问到通过onNewIntent()传递过来的最新Intent数据。一个常见的处理模式是在onNewIntent()中更新Activity内部的数据并在onResume()中根据新数据刷新UI。override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) // 关键必须调用setIntent否则getIntent()拿到的还是旧的 setIntent(intent) // 解析新Intent中的数据 val newData intent?.getStringExtra(key) // 更新ViewModel或内部状态 viewModel.updateData(newData) } override fun onResume() { super.onResume() // 此时UI刷新可以基于onNewIntent中更新的数据 viewModel.data.observe(this) { data - updateUI(data) } }4.2 setIntent()的重要性这是singleTask开发中最容易踩的坑之一。Activity的getIntent()方法返回的永远是创建该Activity实例时传入的第一个Intent。如果不手动调用setIntent(newIntent)那么在onNewIntent()之后getIntent()拿到的仍然是旧的Intent数据会导致数据不一致。务必在onNewIntent()中调用setIntent(intent)。4.3 处理多实例启动与Intent标志位有时我们可能希望即使目标Activity是singleTask也强制启动一个新的实例在一个新的Task里。这可以通过给Intent添加FLAG_ACTIVITY_MULTIPLE_TASK标志来实现通常与FLAG_ACTIVITY_NEW_TASK结合使用。val intent Intent(this, SingleTaskActivity::class.java).apply { flags Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK } startActivity(intent)这个组合标志会告诉系统“忽略现有的Task直接为这个Activity创建一个新的Task即使它的启动模式是singleTask”。这在需要并行多个独立任务流时如文档编辑应用打开多个文件可能会用到但要谨慎使用因为它会创建多个singleTask实例违背了其设计初衷。5. 常见问题排查与实战避坑指南在实际开发中singleTask引发的问题往往隐蔽且令人困惑。下面是我总结的几个典型场景和排查思路。5.1 问题一从singleTask页面启动其他页面后回退行为异常现象从singleTask的HomeActivity启动了一个DetailActivity用户在DetailActivity点击返回期望回到HomeActivity但有时却直接回到了桌面或上一个应用。根因分析这通常是因为DetailActivity被启动到了一个错误的Task中。可能的原因有DetailActivity自己设置了launchModesingleInstance或错误的taskAffinity。启动DetailActivity的Intent包含了FLAG_ACTIVITY_NEW_TASK且系统没有找到匹配affinity的现有Task于是创建了一个新的、独立的Task来存放DetailActivity。当这个Task里只有一个DetailActivity并销毁后整个Task就空了系统自然会退回到上一个活跃的Task可能是桌面。解决方案检查DetailActivity的启动模式和taskAffinity确保其与HomeActivity的Task兼容。除非有特殊需求否则从singleTaskActivity内部启动普通Activity时不要添加FLAG_ACTIVITY_NEW_TASK标志。可以使用adb shell dumpsys activity activities命令在问题发生时查看所有Task和栈的状态这是最直接的诊断工具。5.2 问题二通过Deep Link或通知跳转singleTask页面数据未更新现象应用在后台用户点击一个携带新参数的通知期望打开singleTask的MainActivity并显示新内容但App前台后显示的却是旧数据。排查步骤首先检查onNewIntent()是否被调用在MainActivity的onNewIntent()方法中打日志。检查是否调用了setIntent()如果没调用getIntent()拿不到新数据。检查Intent的配置对于通过PendingIntent发起的启动如通知需要设置FLAG_UPDATE_CURRENT或FLAG_CANCEL_CURRENT来更新Intent中的数据。同时确保PendingIntent的requestCode不同或者使用Mutable的PendingIntent。val pendingIntent PendingIntent.getActivity( context, uniqueRequestCode, // 使用唯一请求码或基于数据生成哈希值 intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE // 根据目标API级别选择 )处理后台进程被杀如果App进程在后台被系统杀死点击通知会先创建进程和Activity实例此时走的是onCreate()而不是onNewIntent()。因此数据刷新的逻辑不能只放在onNewIntent()里在onCreate()中也要根据Intent初始化数据。可以通过判断savedInstanceState是否为null来区分冷启动和热启动。5.3 问题三singleTask Activity的实例似乎有多个现象理论上singleTask在一个Task里应该只有一个实例但日志显示onCreate被调用了多次。可能原因不同的taskAffinity如果该Activity被不同的组件以不同的taskAffinity启动系统会为每个不同的affinity创建独立的Task每个Task里都可以有一个该Activity的实例。检查所有启动它的Intent和Manifest中的taskAffinity设置。使用了FLAG_ACTIVITY_MULTIPLE_TASK如上文所述这个标志会强制创建新实例和新Task。配置变更导致重建屏幕旋转等配置变更会导致Activity销毁重建。这不是singleTask逻辑的复用而是生命周期内的重建。此时onCreate会被调用但Intent是旧的除非你在onSaveInstanceState中保存了新Intent的数据。这属于Android基础生命周期管理问题。5.4 调试利器adb shell dumpsys activity当栈关系变得复杂时命令行工具是终极武器。在终端执行adb shell dumpsys activity activities | grep -A 20 -B 5 “Hist”或者更直观地使用adb shell dumpsys activity activities输出全部信息然后搜索你的Activity类名或Task id。你会看到类似下面的结构* Task id #100 affinitycom.example.app ... * Hist #3: ActivityRecord{... com.example.app/.DetailActivity} * Hist #2: ActivityRecord{... com.example.app/.SingleTaskActivity} * Hist #1: ActivityRecord{... com.example.app/.MainActivity}这清晰地展示了Task的ID、affinity以及栈内Activity从底到顶#1是栈底的历史记录。通过对比操作前后的dump结果你可以精确验证singleTask的启动、复用和清栈行为是否符合预期。6. 设计模式与最佳实践理解了原理和坑点我们来看看如何正确、优雅地使用singleTask。6.1 何时使用singleTask应用主入口Launcher Activity这是最常见的场景。确保无论从应用内部何处跳转回到主页时都是一个干净、唯一的实例避免主页重复堆叠。登录/认证页面当用户会话过期或在任何页面需要重新登录时跳转到登录页。使用singleTask可以清理掉登录页之上所有的历史页面这些页面需要登录态保证用户登录后看到一个干净的栈。支付流程、内容发布等关键且独立的功能模块这些流程通常希望独占一个任务栈流程结束后可以干净地退出或回到指定页面不受其他页面干扰。作为Deep Link或通知的目标页确保通过外部链接进入应用时总是定位到同一个核心实例并能够正确传递和处理新的Intent数据。6.2 配合clearTaskOnLaunch与finishOnTaskLaunch在Manifest中还有两个属性可以与singleTask协同工作进一步控制Task的行为android:clearTaskOnLaunchtrue设置此属性的Activity必须是Task的根Activity每当用户从Launcher再次启动该Task时即Task从后台回到前台系统会清除该Task中根Activity之上的所有其他Activity。这对于主页非常有用确保用户每次从图标点击进入都看到一个“全新”的主页。android:finishOnTaskLaunchtrue设置此属性的Activity当用户再次启动其所属的Task时从后台带到前台该Activity自身会被finish掉。这适用于一些临时性的、一次性的页面。6.3 架构层面的思考ViewModel与单例模式由于singleTaskActivity可能会被复用并接收新的Intent其UI状态和数据管理需要特别设计。ViewModel是首选将页面数据保存在与Activity生命周期解耦的ViewModel中。在onNewIntent()里更新ViewModel的数据源UI通过观察LiveData或StateFlow自动刷新。这样即使Activity因配置变更重建数据也不会丢失。谨慎使用单例或静态变量虽然它们可以跨Activity实例共享数据但要妥善处理数据清理避免内存泄漏和陈旧数据。更好的方式是通过Application作用域的依赖注入容器如Hilt来管理共享的业务逻辑层数据。Intent是参数不是状态树立一个观念Intent传递的是“启动参数”而页面的“状态”如列表滚动位置、表单填写内容应该由ViewModel或SavedStateHandle来管理。在onNewIntent()中只做参数的解析和状态源的更新。7. 总结与个人心得singleTask不是一个可以死记硬背的简单规则。它是一套关于Android任务栈管理的精密协议。我个人的经验是在决定一个Activity是否使用singleTask前先在白板或纸上画出你期望的用户导航路径和栈结构。问自己几个问题这个页面应该是流程的绝对起点吗从其他路径回到这个页面时它之上的页面是否都应该被清除这个页面需要独立处理来自外部的多次启动请求吗在实际编码中养成三个习惯始终在onNewIntent()中调用setIntent()。在onCreate()和onNewIntent()中共享同一段数据初始化/更新逻辑以覆盖冷启动和热启动所有场景。遇到诡异的导航问题时第一时间使用adb shell dumpsys activity activities让系统告诉你真实的栈状态而不是靠猜测。最后不要滥用singleTask。大多数页面使用默认的standard模式就好。singleTask是一种强大的工具但也增加了栈管理的复杂度。用得其所它能带来清晰的导航结构和良好的用户体验用错地方它就是滋生Bug的温床。理解它敬畏它然后谨慎地使用它。

相关新闻

NVIDIA Profile Inspector终极汉化教程:5个核心步骤实现显卡设置完全中文化

NVIDIA Profile Inspector终极汉化教程:5个核心步骤实现显卡设置完全中文化

NVIDIA Profile Inspector终极汉化教程:5个核心步骤实现显卡设置完全中文化 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 还在为NVIDIA Profile Inspector的英文界面感到困惑吗&#xff1…

2026/8/1 7:43:03 阅读更多 →
XNBCLI终极指南:5分钟掌握《星露谷物语》XNB资源处理技巧

XNBCLI终极指南:5分钟掌握《星露谷物语》XNB资源处理技巧

XNBCLI终极指南:5分钟掌握《星露谷物语》XNB资源处理技巧 【免费下载链接】xnbcli A CLI tool for XNB packing/unpacking purpose built for Stardew Valley. 项目地址: https://gitcode.com/gh_mirrors/xn/xnbcli 你是否曾经想为《星露谷物语》制作个性化模…

2026/8/1 7:43:03 阅读更多 →
mysql期末:InnoAI SQL 助手

mysql期末:InnoAI SQL 助手

mysql账户:root密码:123456项目前依赖安装:安装python解释器:python后续安装以及检查版等:python关于ai依赖安装:建库见表以及查看内容:通过通过腾讯云建立token:脚本目录&#xff1…

2026/8/1 7:43:03 阅读更多 →

最新新闻

5大痛点解决指南:BetterGI如何用AI视觉技术重构你的原神体验

5大痛点解决指南:BetterGI如何用AI视觉技术重构你的原神体验

5大痛点解决指南:BetterGI如何用AI视觉技术重构你的原神体验 【免费下载链接】better-genshin-impact 📦BetterGI 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集/挖矿/锄地 | 一条龙 | 全连音…

2026/8/2 10:11:28 阅读更多 →
STM32驱动Grove心率传感器:I2C通信、滤波算法与低功耗设计实战

STM32驱动Grove心率传感器:I2C通信、滤波算法与低功耗设计实战

1. 项目概述:从“Grove - 指夹式心率传感器”说起最近在捣鼓一个健康监测的小项目,核心是需要一个稳定、易用的心率检测模块。市面上心率传感器不少,但要么接线复杂,要么算法需要自己从头写,对快速原型开发不太友好。直…

2026/8/2 10:11:28 阅读更多 →
MPR121电容触摸传感器:从I2C通信到智能调光台灯实战

MPR121电容触摸传感器:从I2C通信到智能调光台灯实战

1. 项目概述:从“触摸”到“感知”的桥梁 在嵌入式开发和物联网项目中,我们常常需要一种直观、可靠且易于集成的人机交互方式。传统的机械按键虽然经典,但存在物理磨损、寿命有限、防水防尘性能差等问题。当我在一个智能家居控制面板的项目中…

2026/8/2 10:11:28 阅读更多 →
终极本地Cookie导出指南:3分钟掌握浏览器Cookie安全管理

终极本地Cookie导出指南:3分钟掌握浏览器Cookie安全管理

终极本地Cookie导出指南:3分钟掌握浏览器Cookie安全管理 【免费下载链接】Get-cookies.txt-LOCALLY Get cookies.txt, NEVER send information outside. 项目地址: https://gitcode.com/gh_mirrors/ge/Get-cookies.txt-LOCALLY 本地Cookie导出和浏览器扩展安…

2026/8/2 10:11:28 阅读更多 →
125、YOLOv8改进实战:小目标检测痛点分析——TAL标签分配优化与超分辨率辅助检测方案

125、YOLOv8改进实战:小目标检测痛点分析——TAL标签分配优化与超分辨率辅助检测方案

125、YOLOv8改进实战:小目标检测痛点分析——TAL标签分配优化与超分辨率辅助检测方案 从一次真实调试说起 上个月帮一个遥感团队调YOLOv8,他们检测机场跑道上的小飞机,模型跑出来的结果让我血压直接拉满——大飞机框得漂漂亮亮,小飞机要么漏检,要么框偏到隔壁跑道上去。…

2026/8/2 10:10:28 阅读更多 →
GPT-5.4持久化状态与200万上下文窗口:AI从工具到协作者的范式革命

GPT-5.4持久化状态与200万上下文窗口:AI从工具到协作者的范式革命

1. 项目概述:当“持久化状态”成为AI的标配最近圈子里关于GPT-5.4的传闻沸沸扬扬,核心就两点:200万级别的上下文窗口,以及一个听起来更“科幻”的特性——持久化状态。作为一名长期跟大模型打交道的从业者,我第一反应不…

2026/8/2 10:10:28 阅读更多 →

日新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/2 0:00:38 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/2 0:00:38 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:38 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/2 0:00:38 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/2 0:00:38 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:38 阅读更多 →

月新闻

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

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

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

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

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

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

2026/8/2 2:47:48 阅读更多 →
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/2 0:23:22 阅读更多 →