HarmonyOS应用实战-启示散页-46-文章素材别混进应用包:把 CSDN 图片和运行资源分开管理
2026/7/28 1:03:01 网站建设 项目流程

HarmonyOS应用实战-启示散页-46-文章素材别混进应用包:把 CSDN 图片和运行资源分开管理

发布前做包体复查时,最容易被忽略的一类问题不是“图片太大”,而是“这张图片本来就不该进包”。答案之书这类项目经常同时维护应用源码、商店截图、CSDN 文章封面、流程图和结构图。目录一乱,文章用的 PNG 很容易被拷进entry/src/main/resources/base/media,最后 HAP 变大,资源来源说不清,发布复盘也不知道该删哪一个文件。

这篇文章只解决一个具体问题:CSDN 文章素材如何和 HarmonyOS 运行资源彻底分开。读完后你应该能拿到四个结果:

  1. 判断一张图片到底服务文章、商店发布,还是应用运行时。
  2. 用资源账本解释包体里每个新增文件的 owner。
  3. 用脚本在提交前拦住文章图片误入resourcesrawfile
  4. 把检查结果写进发布清单,而不是只说“构建通

先还原一次真实事故链

假设发布前发现 HAP 比上一个版本多了几百 KB。第一反应通常是压缩图片、删日志、查依赖。但继续往下看,发现新增文件里有the_book_of_answers_46_cover.pngthe_book_of_answers_46_flow.png这类文章图片。它们不是页面图标,也不是启动页素材,只是为了 CSDN 文章排版准备的说明图。

这时问题已经不是压缩率,而是资源归属失控:

现象真实原因后果
HAP 包体变大文章 PNG 被复制进运行资源发布包携带无用素材
删除图片怕影响页面没有 owner 记录不敢清理资源目录
文章换图后应用也变化共用同一张文件内容发布影响应用运行
审核截图和运行资源混在一起发布素材没有独立目录复盘时找不到证据边界

已核对的当前目录边界是:本系列文章图片位于media/the_book_of_answers/46/,应用运行资源应由entrylibraryHARlibraryHSP各自模块管理。本文不声称已经改过应用源码,只给出可落地的检查与隔离方法。

三类图片先分清 owner

资源治理的第一步不是写脚本,而是给每类图片命名。只看后缀和尺寸不够,文章封面、商店截图、应用图标都可能是 PNG;真正能区分它们的是“谁消费它”。

类型推荐目录消费方是否进入 HAP
CSDN 文章图media/the_book_of_answers/<no>/Markdown / CSDN 编辑器
商店截图release/screenshots/或发布清单目录AGC 提交材料
应用运行图标entry/src/main/resources/base/media/ArkUI$r('app.media.xxx')
默认题库 rawfileentry/src/main/resources/rawfile/SeedLoader/$rawfile(...)
HSP 自带组件资源libraryHSP/src/main/resources/HSP 页面或组件

这个表的作用很直接:如果一张图只是 Markdown 文章里的流程图引用,它就不应该出现在entry/src/main/resources。如果一张图被 ArkUI 页面通过$r('app.media.xxx')引用,它就不应该放在文章素材目录里。

用资源账本记录新增文件

轻量项目不一定需要复杂资产平台,但至少要有一份可读的资源账本。账本不参与运行时逻辑,只服务发布复查:谁加了文件、文件服务什么、是否打包、能否删除。

typeAssetOwner='article'|'agcScreenshot'|'entryRuntime'|'harRuntime'|'hspRuntime'|'rawSeed';interfaceResourceLedgerItem{path:string;owner:AssetOwner;purpose:string;packagedInHap:boolean;referencedBy:string;removableAfterPublish:boolean;}

这段模型的重点不是字段多,而是ownerpackagedInHap。文章图的packagedInHap必须是false;运行资源的referencedBy必须能指向具体页面、组件或启动服务。只要这两项说不清,就不要把文件留进提交。

一条合格记录可以长这样:

{"path":"media/the_book_of_answers/46/the_book_of_answers_46_flow.png","owner":"article","purpose":"第46篇CSDN流程图","packagedInHap":false,"referencedBy":"HarmonyOS应用实战-启示散页-46.md","removableAfterPublish":false}

如果同样的文件被复制进entry/src/main/resources/base/media/,账本就应该报错,而不是让它混进发布包。

HarmonyOS 运行资源只认模块目录

HarmonyOS 工程里,运行资源有明确归属:element放字符串、颜色和尺寸,media放图标和图片,profile放路由或配置,rawfile放保留原始格式的资源。文章图片不属于其中任何一类。

entry/src/main/resources/ base/ element/ string.json color.json media/ app_icon.png home_empty_deck.png profile/ main_pages.json router_map.json rawfile/ seed/default_deck.json media/the_book_of_answers/46/ the_book_of_answers_46_cover.png the_book_of_answers_46_flow.png the_book_of_answers_46_structure.png

这里的分界线很硬:home_empty_deck.png如果被首页Image($r('app.media.home_empty_deck'))使用,就应该在运行资源目录;the_book_of_answers_46_flow.png只被 Markdown 引用,就应该留在文章目录。不要因为两者都是 PNG 就放到同一个地方。

页面引用运行资源时要能说清用途

真正需要进入应用包的图片,也不能只靠文件名存在。页面应该通过$r引用模块内资源,并且文件名能说明业务用途。

@Componentstruct EmptyDeckPanel{build(){Column({space:12}){Image($r('app.media.home_empty_deck')).width(120).height(120)Text($r('app.string.home_empty_deck_title'))Text($r('app.string.home_empty_deck_desc'))}}}

这段代码的 owner 很清楚:home_empty_deck服务首页空题库状态,属于运行资源,可以进入 HAP。与它相对,CSDN 的文章流程图没有任何 ArkUI 引用,不应该为了“方便查看”放进base/media

资源配置也要保持同样边界:

{ "module": { "name": "entry", "type": "entry", "srcEntry": "./ets/Application/AbilityStage.ets", "description": "$string:module_desc", "mainElement": "EntryAbility", "pages": "$profile:main_pages" } }

module.json5只描述模块运行入口和资源配置,不应该引用文章素材目录。文章和发布说明可以描述应用,但不能变成应用的构建输入。

提交前先跑两组扫描

第一个扫描从文章出发:确认 Markdown 引用的都是文章目录下的 PNG,而且文件存在。

$article="C:\Users\ADcaing\Desktop\csdn\HarmonyOS应用实战-启示散页-46-文章素材别混进应用包:把 CSDN 图片和运行资源分开管理.md"$root=Split-Path-Parent$article$refs=Select-String-LiteralPath$article-Pattern'!\[[^\]]+\]\(([^)]+\.png)\)'-AllMatchesforeach($matchin$refs.Matches){$relative=$match.Groups[1].Value$full=Join-Path$root$relativeif(-not(Test-Path-LiteralPath$full)){throw"文章图片不存在:$relative"}if($relative-notlike"media/the_book_of_answers/46/*.png"){throw"第46篇图片路径越界:$relative"}}

第二个扫描从应用工程出发:确认运行资源目录里没有文章素材特征词。这里的目标不是证明源码一定正确,而是拦住最常见的误复制。

$project="D:\ProgramData\huawei\lesson\The_Book_of_Answers"$resourceRoots= @("$project\entry\src\main\resources","$project\libraryHAR\src\main\resources","$project\libraryHSP\src\main\resources")foreach($rootin$resourceRoots){if(Test-Path-LiteralPath$root){$hit=Get-ChildItem-LiteralPath$root-Recurse-File|Where-Object{$_.Name-match'the_book_of_answers|csdn|article|cover_flow|structure'}if($hit){$hit|ForEach-Object{Write-Output$_.FullName}throw"文章素材疑似进入应用运行资源"}}}

这两个扫描方向不同:一个保证文章能正常发布,一个保证应用包不带文章素材。只做其中一个都不完整。

包体复查要看“新增资源来源”

如果构建后发现包体变大,排查顺序建议从新增资源来源开始,而不是直接压缩。压缩只能降低体积,不能解决不该打包的问题。

$before=Get-Content".\release\resource-list-before.txt"$after=Get-Content".\release\resource-list-after.txt"$added=Compare-Object$before$after|Where-Object{$_.SideIndicator-eq"=>"}$added|ForEach-Object{$path=$_.InputObjectif($path-match'the_book_of_answers|csdn|article'){throw"发现文章素材进入包体清单:$path"}Write-Output"新增资源待确认 owner:$path"}

实际项目里可以从构建产物、资源清单或手工导出的文件列表中拿before/after。重点是每个新增资源都要回答两个问题:它被哪个运行页面使用?如果删除它,应用哪条路径会失败?

反例:把文章目录当成备用素材库

最危险的写法不是偶尔复制一张图,而是团队默认把media当成素材库。比如首页缺一个空态图,就从 CSDN 文章里挑一张流程图放进resources/base/media;发布截图缺一张说明图,又从运行资源里复制出去改尺寸。几轮之后,任何图片都说不清来源。

反例通常有三个症状:

症状为什么危险正确处理
文件名只有cover.png无法判断属于文章还是页面home_empty_deck.pngarticle_46_flow.png区分用途
文章图和运行图共用路径内容发布会影响应用包文章目录和资源目录物理隔离
删除资源只靠人工记忆发布前不敢清理资源账本记录 owner 和引用点

遇到这种情况,不要先批量重命名。先按 owner 分类,把不该进入 HAP 的文件移出运行资源,再补账本和扫描脚本。否则只是把混乱资源换了一批新名字。

验证清单

第 46 篇文章发布前,我建议按这张清单复查:

  • Markdown 中 3 张图片都指向media/the_book_of_answers/46/
  • 3 张图片都是本地 PNG,且文件真实存在。
  • entry/src/main/resourceslibraryHAR/src/main/resourceslibraryHSP/src/main/resources中没有the_book_of_answerscsdnarticle等文章素材命名。
  • 应用运行资源里的新增图片能找到 ArkUI$r('app.media.xxx')或启动服务引用。
  • 发布清单记录文章素材目录与应用资源目录相互独立。
  • 包体变大时先查新增资源 owner,再考虑压缩。

这里没有做真机运行验证,也没有上传 CSDN。本文给出的验证是本地文件、Markdown 引用和工程资源边界检查;如果要证明发布结果,还需要在 CSDN 编辑器里完成图片上传和正文预览。

常见问题与定位

现象先看哪里处理
HAP 体积突然变大新增资源清单找出是否有文章 PNG 进入 resources
文章图片发布后丢失Markdown 图片路径确认本地 PNG 存在,发布前上传到 CSDN 图床
删除某张图担心影响应用是否有$r$rawfile引用没有运行引用且 owner 是 article,就不应在 HAP
同名图片到处都有文件命名规则按业务用途重命名,不按临时来源命名
rawfile 里出现说明图rawfile 消费方rawfile 只留 SeedLoader 等真实运行输入

排查时先从路径入手。文章素材路径应该能读出文章编号,运行资源路径应该能读出页面或组件用途。路径都说不清时,代码层面的引用通常也会跟着混乱。

小结

文章素材和运行资源的边界,本质上是发布责任边界。CSDN 图片服务内容表达,商店截图服务提交材料,resourcesrawfile服务应用运行。把这三类资产混在一起,包体、审核和排障都会变得模糊。更稳的做法是:目录先隔离,账本写 owner,提交前双向扫描,包体复查只接受能解释来源的新增资源。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询