Unity Addressables资源热更新实战:从配置到部署全流程解析
1. 项目概述为什么我们需要Addressables在Unity项目开发中尤其是移动端和在线游戏资源管理一直是个老大难问题。回想一下你是不是也经历过这样的场景为了修复一个UI贴图错误或者更新一个角色模型不得不重新打包整个APK或IPA然后引导用户去应用商店下载几百兆甚至上G的更新包用户流失率往往就发生在漫长的下载等待中。传统的AssetBundle虽然解决了资源打包和依赖问题但其管理、加载和更新流程相当繁琐需要开发者自己处理依赖链、版本比对、差分下载等一系列复杂逻辑。Unity Addressables可寻址资源系统的出现就是为了彻底解决这个痛点。它不是一个全新的技术而是对AssetBundle工作流的一次深度封装和现代化升级。你可以把它理解为一个“智能资源管家”。它的核心思想是“以地址为中心”你不再直接操作GameObject或AssetBundle文件而是通过一个唯一的地址一个字符串来请求资源。至于这个地址背后对应的是本地打包的资源还是需要从网络下载的更新包Addressables系统会自动帮你处理。这次我们要实战演练的就是从零开始配置一个支持热更新的Addressables系统并完成动态更新的全流程。这对于需要频繁更新活动内容、修复线上BUG、或者采用“小包体动态下载”发行策略的项目来说是必须掌握的技能。无论你是客户端主程还是负责资源管线的TA理解这套流程都能让你在应对资源更新需求时更加从容。2. 核心概念与前期配置2.1 Addressables 核心四要素在动手之前必须理清Addressables的四个核心概念这是理解其工作流的基础。Group资源组这是资源的逻辑容器。你可以根据更新频率、资源类型等策略来划分组。例如将启动必需的资源如登录界面、核心代码放在一个“本地”组将活动资源、时装等放在“远程”组。每个组在打包时会生成对应的AssetBundle文件。Address地址每个资源的唯一标识符。你可以使用资源的路径、自定义的字符串或者其GUID作为地址。加载资源时就使用这个地址。Label标签一个资源可以拥有多个标签。标签允许你进行批量操作比如一次性加载所有带有“UI/Login”标签的贴图和预制体非常灵活。Catalog目录这是一个JSON格式的清单文件它记录了所有资源组、资源地址、依赖关系以及它们的哈希值用于版本比对。本地和远程各有一份Catalog系统通过比对它们来决定需要下载哪些更新。2.2 项目初始化与基础配置首先通过Package Manager安装Addressables包。建议使用1.19.0及以上版本以获得更稳定的远程构建和更新功能。安装完成后打开Window - Asset Management - Addressables - Groups窗口。首次打开时系统会提示你初始化Addressables设置。这一步会在Assets目录下创建AddressableAssetsData文件夹里面包含了整个系统的配置数据。接下来是关键的一步构建路径配置。在Groups窗口点击Tools - Profiles。这里我们需要设置几个关键的路径变量LocalBuildPath: 本地构建输出路径如[UnityProject]/ServerData/StandaloneWindows64平台相关。LocalLoadPath: 本地加载路径通常设为[UnityProject]/ServerData/StandaloneWindows64与构建路径一致用于开发阶段直接加载。RemoteBuildPath: 远程构建输出路径这是你准备上传到资源服务器的根目录如[BuildTarget]。RemoteLoadPath: 远程资源加载的URL基地址如http://your-cdn-server/addressables/[BuildTarget]。注意RemoteLoadPath是运行时动态拼接资源路径的基础。例如一个资源的远程地址可能是http://your-cdn-server/addressables/StandaloneWindows64/bundleName.bundle。确保这个URL在真机或模拟器环境下是可访问的。配置好Profile后在Groups窗口的Build - New Build - Default Build Script中选择你刚配置的Profile。然后我们需要创建一个“远程”资源组。右键Groups面板选择Create Group - Packed Assets命名为“RemoteAssets”。创建后在Inspector面板中将其Build Load Paths从“Default”改为你Profile中定义的“Remote”路径。这意味着这个组里的资源将会被构建到远程路径并且运行时期望从远程URL加载。3. 资源标记与打包策略设计3.1 高效标记资源与分组策略将资源拖入对应的Group就完成了基本的标记。但更高效的做法是使用批量标记。你可以选中多个资源在Inspector的Addressables面板中统一设置它们的Address和Labels。分组策略是性能与体验平衡的艺术按更新频率分组永不更新的基础包如核心框架代码放在本地组每周更新的活动资源放在一个远程组每天可能更新的配置表放在另一个更小的远程组。这样可以最小化每次热更的下载量。按资源类型分组将所有音频打成一个包所有角色模型打成另一个包。这有利于内存管理和专项优化但可能导致一个资源的更新牵连整个大组。按场景/功能模块分组每个关卡或每个大型系统如“召唤系统”、“公会系统”的资源独立成组。这符合DLC式的更新逻辑用户体验好但管理稍复杂。一个常见的混合策略是一个本地组包含启动资源和首包资源 多个按功能划分的远程组。对于远程组务必勾选Inspector - Advanced Options - Contiguous Bundles这能优化资源在包内的存储布局提升加载效率。3.2 构建玩家与构建目录配置好资源后需要进行第一次构建。构建分为两部分构建内容Build Content点击Build - New Build - Default Build Script。这个过程会执行资源打包、依赖分析并在你配置的LocalBuildPath和RemoteBuildPath下生成AssetBundle文件、Catalog文件catalog.json及其哈希文件catalog.json.hash。更新目录Update Catalog这个步骤是可选的但在热更流程中至关重要。它允许你只更新资源内容而不改变资源的寻址逻辑。当你只是修改了某个贴图而没有新增或删除资源地址时使用“Update a Previous Build”可以极大缩短构建时间。构建完成后观察输出目录。你会看到每个资源组对应一个.bundle文件一个catalog.json文件记录了所有资源的索引。远程热更的核心就是让客户端用本地的catalog.json与服务器上的最新catalog.json进行比对从而计算出需要下载的差异文件列表。4. 动态更新流程的代码实现4.1 初始化与更新检查所有的资源加载和更新操作都通过Addressables这个静态类进行。首先我们需要在游戏启动时初始化并检查更新。using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using System.Collections.Generic; public class AddressablesUpdater : MonoBehaviour { public string catalogUpdateUrl http://your-cdn-server/addressables/StandaloneWindows64/catalog.json; private Liststring catalogsToUpdate new Liststring(); async void Start() { // 1. 初始化Addressables系统 await Addressables.InitializeAsync().Task; // 2. 检查Catalog更新 await CheckForCatalogUpdates(); } async Task CheckForCatalogUpdates() { // 获取当前已加载的Catalog列表 var catalogs Addressables.ResourceLocators; foreach (var locator in catalogs) { if (locator.LocatorId is UnityEngine.ResourceManagement.ResourceLocations.ContentCatalogData ccd) { catalogsToUpdate.Add(ccd.location.PrimaryKey); } } // 开始检查更新 var checkHandle Addressables.CheckForCatalogUpdates(false); await checkHandle.Task; if (checkHandle.Status AsyncOperationStatus.Succeeded) { var catalogsWithUpdate checkHandle.Result; if (catalogsWithUpdate.Count 0) { Debug.Log($发现 {catalogsWithUpdate.Count} 个Catalog需要更新); // 执行Catalog更新 await UpdateCatalogs(catalogsWithUpdate); } else { Debug.Log(Catalog已是最新开始检查内容更新); await CheckForContentUpdates(); } } Addressables.Release(checkHandle); } }4.2 执行Catalog与内容更新检查到Catalog更新后需要先更新Catalog因为新的Catalog包含了最新的资源索引。async Task UpdateCatalogs(Liststring catalogsToUpdate) { Debug.Log(开始更新Catalog...); var updateHandle Addressables.UpdateCatalogs(catalogsToUpdate, false); await updateHandle.Task; if (updateHandle.Status AsyncOperationStatus.Succeeded) { Debug.Log(Catalog更新成功重新初始化资源定位器); // Catalog更新后需要重新初始化以加载新的资源索引 await Addressables.InitializeAsync().Task; // 然后检查基于新Catalog的内容更新 await CheckForContentUpdates(); } else { Debug.LogError($Catalog更新失败: {updateHandle.OperationException}); // 处理失败逻辑如重试或提示用户 } Addressables.Release(updateHandle); }更新完Catalog就可以检查具体的资源内容更新了。async Task CheckForContentUpdates() { Debug.Log(开始检查资源内容更新...); // 获取所有需要更新的资源大小 var sizeCheckHandle Addressables.GetDownloadSizeAsync(); await sizeCheckHandle.Task; long totalDownloadSize sizeCheckHandle.Result; Addressables.Release(sizeCheckHandle); if (totalDownloadSize 0) { Debug.Log($发现需要下载的资源总大小: {totalDownloadSize / 1024.0f / 1024.0f:F2} MB); // 这里可以弹窗提示用户询问是否下载 // 用户确认后开始下载 await DownloadContentUpdates(); } else { Debug.Log(没有需要更新的资源进入游戏); OnUpdateComplete(); } } async Task DownloadContentUpdates() { Debug.Log(开始下载资源更新...); // 执行下载更新 var downloadHandle Addressables.DownloadDependenciesAsync(null, true); // 参数为null表示更新所有资源 // 可以监听下载进度 while (!downloadHandle.IsDone) { float percent downloadHandle.PercentComplete; Debug.Log($下载进度: {percent:P}); // 更新UI进度条 // UpdateProgressUI(percent); await Task.Yield(); } if (downloadHandle.Status AsyncOperationStatus.Succeeded) { Debug.Log(资源下载更新完成); // 清理旧的、未使用的资源 Addressables.CleanBundleCache(); OnUpdateComplete(); } else { Debug.LogError($资源下载失败: {downloadHandle.OperationException}); } Addressables.Release(downloadHandle); } void OnUpdateComplete() { // 所有更新完成可以加载主场景或进入游戏逻辑 Debug.Log(热更流程全部结束准备进入游戏); // Addressables.LoadSceneAsync(MainScene); }4.3 资源加载与生命周期管理更新完成后就可以像使用Resources一样使用Addressables加载资源了但管理方式更优。public class ResourceLoader : MonoBehaviour { public AssetReferenceGameObject playerPrefabRef; // 在Inspector中拖入 private GameObject instantiatedPlayer; private AsyncOperationHandleGameObject loadHandle; async void LoadPlayer() { // 通过AssetReference加载推荐类型安全 loadHandle playerPrefabRef.LoadAssetAsyncGameObject(); await loadHandle.Task; if (loadHandle.Status AsyncOperationStatus.Succeeded) { instantiatedPlayer Instantiate(loadHandle.Result); } } async void LoadByAddress(string address) { // 通过地址字符串加载 var handle Addressables.LoadAssetAsyncGameObject(address); await handle.Task; if (handle.Status AsyncOperationStatus.Succeeded) { Instantiate(handle.Result); } // 注意这种方式需要手动管理Handle的释放 // 对于需要长期使用的资源可以不立即释放在场景卸载时统一释放 // Addressables.Release(handle); } void OnDestroy() { // 释放资源Handle if (loadHandle.IsValid()) { Addressables.Release(loadHandle); } // 如果实例化的对象也是通过Addressables加载的且需要销毁时回收使用Addressables.ReleaseInstance if (instantiatedPlayer ! null) { Addressables.ReleaseInstance(instantiatedPlayer); } } }5. 服务器部署与持续集成5.1 资源服务器配置Addressables本身不提供服务器你需要将RemoteBuildPath下的所有文件包括.bundle、.json、.hash文件上传到一台Web服务器或CDN上并确保其支持HTTP/HTTPS访问且MIME类型配置正确尤其是.bundle文件可能需要添加application/octet-stream。一个简单的目录结构如下http://your-cdn-server/addressables/ ├── StandaloneWindows64/ │ ├── catalog.json │ ├── catalog.json.hash │ ├── remoteassets_assets_all_xxx.bundle │ └── ... ├── Android/ │ ├── catalog.json │ └── ... └── iOS/ ├── catalog.json └── ...5.2 自动化构建与上传手动构建和上传效率低下且易出错。我们可以将其集成到CI/CD流程中如Jenkins, GitLab CI, GitHub Actions。以下是一个简化的GitHub Actions工作流概念name: Build and Deploy Addressables on: push: tags: - v* # 当打上v开头的tag时触发 jobs: build-and-deploy: runs-on: windows-latest steps: - uses: actions/checkoutv3 - name: Cache Library uses: actions/cachev3 with: path: Library key: Library-${{ hashFiles(**/Packages/packages-lock.json) }} - name: Build Addressables run: | # 调用Unity命令行执行Addressables构建 # 需要准备一个Editor脚本调用Addressables.BuildContent()和Addressables.UpdateContent() # 并将构建目标设置为远程 echo Building Addressables Content... - name: Deploy to CDN env: CDN_KEY: ${{ secrets.CDN_ACCESS_KEY }} run: | # 使用工具如aws cli, azcopy, rclone将构建输出的远程目录同步到CDN echo Uploading to CDN...核心是编写一个Editor构建脚本在CI环境中无头运行Unity执行Addressables.BuildContent()并指定BuildScriptPackedMode和远程Profile。6. 实战避坑指南与性能优化6.1 常见问题与排查加载失败报“Invalid Key”错误原因最常见的错误。地址拼写错误、资源未标记为Addressable、或Catalog未更新本地有缓存但服务器资源已变更。排查首先在Groups窗口搜索该地址确认资源存在且地址正确。运行时检查Addressables.ResourceLocators是否包含了该资源的定位器。对于远程资源检查网络可达性及Catalog版本。远程更新时下载进度卡住或失败原因网络不稳定、服务器文件缺失、或本地存储空间不足。排查查看AsyncOperationHandle.OperationException获取详细错误。在真机上检查应用的文件读写权限尤其是Android的WRITE_EXTERNAL_STORAGE权限。确保服务器上的.bundle和.hash文件与catalog.json中的记录完全匹配。内存泄漏Resources未释放原因加载资源后没有正确释放对应的AsyncOperationHandle。每个LoadAssetAsync或InstantiateAsync调用都会返回一个Handle即使资源已经实例化这个Handle也持有引用。解决遵循“谁加载谁释放”的原则。对于场景生命周期内一直使用的资源如主角模型可以在场景卸载时统一释放。对于临时UI在使用完毕后立即调用Addressables.ReleaseInstance(gameObject)和Addressables.Release(handle)。打包后资源丢失原因资源被标记为Addressable但其所在的Group的构建路径配置错误或者资源本身有Missing的依赖。排查使用Analyze - Check for Duplicate Bundle Dependencies工具分析依赖。构建后仔细查看Unity Console的输出日志是否有警告或错误。检查构建输出目录看对应的.bundle文件是否生成。6.2 性能优化要点合并冗余依赖使用Analyze工具集中的Check for Duplicate Bundle Dependencies和Check Resources to Easy Bundle Layout。前者能找出被多个包重复包含的资源如通用材质、字体建议将这些公共资源抽离到独立的共享包中。后者可以根据依赖关系优化资源分组减少包之间的引用。启用内容打包与加载缓存Content Packing Loading Cache在Group的Advanced Options中Content Packing Loading下的选项可以优化。Bundle Mode选择Pack Together by Label可以更精细地控制打包粒度。启用Use Asset Database (fastest)仅在编辑器模式下有效发布时应使用Use Existing Build (requires built groups)。异步加载与分帧大量资源同步加载会卡住主线程。务必使用LoadAssetAsync并配合await或回调。对于需要加载大量资源的场景如进入新关卡可以实现一个分帧加载器每帧只加载固定数量的资源保持游戏流畅。预加载与引用计数对于即将使用的关键资源如下个场景的关卡地图可以在当前场景提前进行异步预加载。使用Addressables.DownloadDependenciesAsync(address)可以只下载但不加载资源到内存。合理利用AssetReference它在Inspector中赋值时其依赖项会在场景加载时自动被引用计数避免被意外卸载。监控与日志在开发阶段打开Addressables - Preferences - Log Runtime Exceptions。发布后可以构建一个简单的资源加载监控系统记录加载耗时、失败率等数据便于线上问题追踪。Addressables资源热更是一个系统工程从资源标记、打包策略到更新逻辑、服务器部署再到性能优化和问题排查环环相扣。一开始可能会觉得配置繁琐但一旦流水线跑通它将为你的项目带来巨大的运维优势。最关键的是理解其“以地址为中心”和“目录驱动更新”的核心思想这样无论遇到什么问题都能从原理层面找到解决方向。在实际项目中建议先在一个小模块上跑通全流程再逐步推广到整个项目。

相关新闻

023、EfficientAdditiveAttention高效加法注意力复现:消除矩阵乘法的YOLOv12注意力改进

023、EfficientAdditiveAttention高效加法注意力复现:消除矩阵乘法的YOLOv12注意力改进

023、EfficientAdditiveAttention高效加法注意力复现:消除矩阵乘法的YOLOv12注意力改进 兄弟们,今天这篇咱们聊个有意思的东西。上周我在调YOLOv12的时候,发现一个特别膈应人的问题——模型跑起来倒是挺快,但一看nvidia-smi&#…

2026/8/5 2:19:03 阅读更多 →
TikTok Shop店群自动化管理系统:秒级轮询监控,竞品一动你3秒内跟进

TikTok Shop店群自动化管理系统:秒级轮询监控,竞品一动你3秒内跟进

TikTok Shop店群自动化管理系统:秒级轮询监控,竞品一动你3秒内跟进 做店群的老板都知道,TikTok Shop的批量抓取采集,是店群运营中最耗人力也最容易出错的环节。 采集竞品数据是店群运营的命脉。但各大平台的反爬系统越来越强&am…

2026/8/5 2:18:03 阅读更多 →
3D打印层错位故障诊断与解决:从机械、电气到软件的全方位排查指南

3D打印层错位故障诊断与解决:从机械、电气到软件的全方位排查指南

1. 从一次失败的打印说起:层错位,3D打印的“骨折”现象我桌上摆着一个刚出炉的打印件,本该是个精致的机械臂关节,现在却像被斜着切了一刀,上半部分和下半部分完美地错开了几毫米。这不是什么艺术创作,而是典…

2026/8/5 2:18:03 阅读更多 →

最新新闻

桌面Agent架构解析:从感知到执行的智能体实现与挑战

桌面Agent架构解析:从感知到执行的智能体实现与挑战

1. 从“玩具”到“伙伴”:桌面Agent的进化与价值重估最近几年,AI领域的热点从大语言模型本身,逐渐转向了如何让这些模型“动起来”,真正成为我们工作流中的一部分。桌面Agent,或者说智能体,就是这个趋势下最…

2026/8/5 2:58:21 阅读更多 →
SCP免密传输全攻略:从SSH密钥原理到自动化部署实战

SCP免密传输全攻略:从SSH密钥原理到自动化部署实战

1. 项目概述:为什么我们需要SCP免密传输?每次从本地往远程服务器传文件,都要输一遍密码,烦不烦?尤其是在做自动化脚本、频繁部署或者批量操作的时候,手动输入密码简直就是效率杀手。我猜点开这篇文章的你&a…

2026/8/5 2:58:21 阅读更多 →
Python代码控制小米智能插座:从局域网通信到自动化场景实战

Python代码控制小米智能插座:从局域网通信到自动化场景实战

1. 项目缘起:为什么需要代码控制智能插座?几年前,我还在用手机App手动开关家里的加湿器和鱼缸灯,直到有一次出差,突然降温,担心家里的热带鱼,才意识到远程、自动控制的重要性。市面上大多数智能…

2026/8/5 2:58:21 阅读更多 →
从ARP协议原理到实战排错:网络通信的底层基石与安全攻防

从ARP协议原理到实战排错:网络通信的底层基石与安全攻防

1. 项目概述:从一次“握手失败”说起那天在GNS3里搭了个简单的实验环境,两台路由器各自连着一台主机,想看看数据包是怎么转发的。拓扑刚配好,主机A ping 主机B,第一个包就卡住了。控制台里没看到预想中的ICMP回显请求&…

2026/8/5 2:58:20 阅读更多 →
STM32 USB虚拟串口(CDC)开发实战:从CubeMX配置到数据通信优化

STM32 USB虚拟串口(CDC)开发实战:从CubeMX配置到数据通信优化

1. 项目概述:为什么我们需要虚拟串口?在嵌入式开发,尤其是基于STM32这类MCU的项目里,串口(UART)调试几乎是工程师的“空气和水”。它简单、直接,是打印日志、传输数据、与上位机通信的首选。但传…

2026/8/5 2:58:20 阅读更多 →
Swagger接口测试实战:从文档生成到动态测试沙箱的深度整合

Swagger接口测试实战:从文档生成到动态测试沙箱的深度整合

1. 项目概述:为什么我们需要整合Swagger进行接口测试?如果你是一名后端开发者,或者正在和API打交道,那么“接口测试”这个词对你来说一定不陌生。从手动在Postman里敲请求,到写一堆自动化脚本,这个过程既繁…

2026/8/5 2:57:20 阅读更多 →

日新闻

Java缓存框架:JetCache

Java缓存框架:JetCache

TOC 一、简介 JetCache 是一个 Java 缓存抽象框架,为不同的缓存解决方案提供了统一的使用方式。 它提供的注解比 Spring Cache 更加强大。 JetCache 的注解支持原生 TTL、两级缓存以及在分布式环境中的自动刷新功能,同时你也可以通过代码直接操作 Cach…

2026/8/5 0:00:43 阅读更多 →
AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

需求:通孔焊盘 十字花;过孔 Via 实心直连;贴片焊盘按需设置 AD 测试版本AD24 很多工程师踩坑:全部统一十字,导致接地过孔阻抗高、大电流发热! 一、快捷键打开规则 PCB 界面按下:D R 展开…

2026/8/5 0:00:43 阅读更多 →
AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

更多请点击: https://kaifayun.com 第一章:AI生成素描效果 AI生成素描效果是计算机视觉与风格迁移技术融合的典型应用,其核心在于将彩色照片或RGB图像转换为具有手绘质感、明暗对比强烈、边缘清晰的单色素描图像。该过程通常依赖于深度学习模…

2026/8/5 0:00:43 阅读更多 →

周新闻

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

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

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

2026/8/4 13:24:41 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

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

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

2026/8/4 11:41:39 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

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

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

2026/8/4 5:26:40 阅读更多 →

月新闻

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

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

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

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

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

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

2026/8/4 11:09:16 阅读更多 →
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/4 13:38:40 阅读更多 →