惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
H
Heimdal Security Blog
Jina AI
Jina AI
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Hacker News
The Hacker News
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
S
Securelist
P
Privacy International News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
博客园 - 叶小钗
J
Java Code Geeks
V
V2EX
博客园 - Franky
Spread Privacy
Spread Privacy
K
Kaspersky official blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Simon Willison's Weblog
Simon Willison's Weblog
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
C
Cybersecurity and Infrastructure Security Agency CISA
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
NISL@THU
NISL@THU
罗磊的独立博客
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
V
Visual Studio Blog

人人都是产品经理

为什么你的产品找不到差异化?90%的失败都卡在第一步上(下) – 人人都是产品经理, 3年从30万到1300万用户、获2200万美元融资,这个AI教育产品用“抽卡”破解了获客难题 – 人人都是产品经理, 园区招商系统怎么做才能真正帮到去化?我加了这一个功能,推广链接转发400次阅读过万 – 人人都是产品经理, AI大事件:OpenAI发完网络安全模型又搞药物研发,小鹏汽车要抓”DeepSeek时刻” – 人人都是产品经理, 电商不是卖货,是一场更残酷的产品经理实战 – 人人都是产品经理, 没想到,活动营销又回来了! – 人人都是产品经理, 为何All-in海外KOC:一场关于AI时代窗口期的豪赌 – 人人都是产品经理, 重新理解企业的内部协作 – 人人都是产品经理, 苹果的 AI 战略到底是什么? – 人人都是产品经理, 医疗智能体·第2讲——合规护城河:等保、PIPL与HIPAA的架构实战 – 人人都是产品经理, 向量知识库五步法:从“答非所问”到“精准回复” – 人人都是产品经理, 鸿蒙PC三方库构建总指挥HPKBUILD(sha)库为例 – 人人都是产品经理, 何时该用LLM?AI产品经理的LLM设计指南 – 人人都是产品经理, 医疗信息领域的需求方、决策方、准入方以及关注点(二) – 人人都是产品经理, 即梦涨价:一场被误读的「傲慢」 – 人人都是产品经理, 面试AI PM必答题:Hermes和OpenClaw的区别,如何讲清楚业务价值 – 人人都是产品经理, AI的下一张船票:世界模型——AI产品经理必须理解的技术拐点 – 人人都是产品经理, 小红书做GEO,怎么让AI信你?记住这 3 个重要信息 – 人人都是产品经理, 5 家印度 AI 初创公司,看看印度 AI 再做什么 – 人人都是产品经理, AI项目跨团队协作:产品技术业务如何不打架 – 人人都是产品经理, Agentic Workflow(智能体工作流):让AI从”答案生成器”变成”数字员工” – 人人都是产品经理, lycium_plusplus 项目全景解读:OpenHarmony 三方库构建的“大管家” – 人人都是产品经理, 从爆单救火到前置履约:两套预采策略,把生鲜大促履约效率拉满 – 人人都是产品经理, 什么时候该补货?我用一轮数据做了一个决定 – 人人都是产品经理, 从“机械兜底”到“动态分流”:AI客服重复进线治理的4大底层逻辑 – 人人都是产品经理, 抖音拼效率,红书拼洞察 – 人人都是产品经理, 全民狂欢与退潮——为什么龙虾这波热潮冷却得如此之快? – 人人都是产品经理, Stripe押注!MPP重塑全球支付 – 人人都是产品经理, 小红书GEO:AI引用你的内容,不是因为你对,而是因为你看起来可信 – 人人都是产品经理, 前百度副总裁押注办公Agent,日韩付费爆发,Manus迎来强劲对手 – 人人都是产品经理, 企事业单位数字化的业务供需本质 – 人人都是产品经理, 医疗智能体·第1讲——医疗信息化重构:从“辅助软件”到“自主智能体”的范式转移 – 人人都是产品经理, 粉丝量就是空气!!! – 人人都是产品经理, 用户说“薯片碎了”,机器回“要买吗?”:意图识别的翻车与破局 – 人人都是产品经理, RAG召回准确率从75到90 我做对了这三件事 – 人人都是产品经理, AI大事件:Anthropic改收费、OpenAI发安全版、手术机器人纳入医保、阿里发布”秒悟” – 人人都是产品经理, Chrome 推出 Skills 新功能,Agent 重塑上网方式 – 人人都是产品经理, GitHub前创始人拿了a16z的1700万美元,做Agent时代的Git – 人人都是产品经理 拷贝或克隆其他 Flutter OH 项目到本地后无法运行 – 人人都是产品经理, 优惠券设计:优惠券创建 – 人人都是产品经理, 不用死磕文档!AI 助手 1 小时搞定飞书 CLI 安装 + 配置 + 知识库 – 人人都是产品经理, 用小龙虾做竞品分析报告:从2天到20分钟,我是怎么做到的 – 人人都是产品经理 用小龙虾做市场分析报告:搞懂这3个公式,市场规模不再靠猜 – 人人都是产品经理, 你早就在做 Harness 工程,只是不知道它叫这个名字 – 人人都是产品经理, Think Long就够?你可能想多了! – 人人都是产品经理, 货代SRM实战:供应商准入怎么做,才能让资源池不是通讯录而是可交付网络? – 人人都是产品经理, 如何做好用户调研?详解基本技巧 – 人人都是产品经理, 木鸟、途家、美团对打,平台春天行动开“卷” – 人人都是产品经理, 入职才发现公司不靠谱?小红书从业者求职避坑指南 – 人人都是产品经理, 美国 AI 三巨头联手封堵,中国 AI 突围之路在何方 – 人人都是产品经理, 小红书,放在需求对面的镜子 – 人人都是产品经理, AI 会带来大规模失业吗? – 人人都是产品经理, 从出单到补货前,我第一次犹豫:该不该放大? – 人人都是产品经理, Flutter 三方库鸿蒙化适配:5 种高效检查方式,快速判断是否需要适配 – 人人都是产品经理, 从做产品进阶拿结果:医美机构产品经理转岗科室运营经理 – 人人都是产品经理, 阿里HappyHorse,一场关于“Token经济”的阳谋 – 人人都是产品经理, To B AI:客户留存落地的观察与思考 – 人人都是产品经理, AI产品的“生命线”——数据采集、标注、清洗的产品化设计 – 人人都是产品经理, 谈谈AI Agent(二):当“孩子”能自己“体验世界”时,你该学什么? – 人人都是产品经理, UI/UX设计师的3层能力进阶,前两层让你活下来,第三层…才是真正的分水岭 – 人人都是产品经理, 2分钟 → 30秒,效率提升75%:B端产品经理如何用「规则枷锁」驯服AI幻觉? – 人人都是产品经理, 还没来得及学OpenClaw,来了个更猛的:Hermes Agent – 人人都是产品经理, AI日报:宇树机器人跑出10m/s刷新世界纪录 – 人人都是产品经理, 一文说透基金互金如何用情绪价值引导用户决策做转化 – 人人都是产品经理, 当浏览器开始替你”看”网页:AI 浏览器正在亲手拆掉它脚下的那张网 – 人人都是产品经理, 0代码,一天时间我Vibe Coding了个网站 – 人人都是产品经理, Hermes 和 OpenClaw 之争,Agent 的能力应该“装上去”还是“长出来”? – 人人都是产品经理 视频生成的“桌子”,字节Seedance 2掀完,阿里快乐马掀 – 人人都是产品经理, 从听不懂到完全信任:我的 Codex 深度产品体验 – 人人都是产品经理, 当虚拟偶像有了北京户口,与真人偶像还有什么区别? – 人人都是产品经理, 会说,远远比会做更重要 —— 对 SBTI 爆火现象的五层观察 – 人人都是产品经理, AI产品经理必看:当“搭环境”比“选模型”更重要,你的认知还在2024年吗? – 人人都是产品经理, 2026年AI产品商业化核心逻辑:从功能demo到规模化营收的3个必破卡点 – 人人都是产品经理, 京东围绕供应链,卷起裤腿下场的那些事儿 – 人人都是产品经理, SBTI一夜刷屏:它赢在了“太会说人话” – 人人都是产品经理, 折扣零售的真相:不是便宜,而是价值感! – 人人都是产品经理, 和甲方吵了一架,最后加钱做了——我学到的ToB产品经理生存法则 – 人人都是产品经理, 和几位小红书操盘手聊了8小时,干货全在这 – 人人都是产品经理, 智谱GLM-5.1登场,开源模型首超Opus4.6!!! – 人人都是产品经理 Anthropic收入凭什么反超OpenAI,终于有人把这事说清楚了 – 人人都是产品经理, 史上最有故事感的技术报告——Claude最强模型Mythos 7个极其精彩的细节 – 人人都是产品经理, 模型不是壁垒,Harness 也不是 – 人人都是产品经理, 抖音本地生活业务思考21 – 人人都是产品经理, Superpowers:145k Star的AI编码框架,到底是什么来头? Superpowers:145k Star的AI编码框架,到底是什么来头? – 人人都是产品经理, OpenAI 的路走错了,Anthropic Harness 解法启示:模型需要实践专科生 – 人人都是产品经理, 画原型图的前一步:设计站点地图 – 人人都是产品经理, 给 DeepSeek 的最后一封催更信 – 人人都是产品经理, 手把手教你用 Claude Code 搭建 AI 营销团队:5 个 Agent、12 项技能,独立完成研究、写作、设计全流程 – 人人都是产品经理, 你以为大模型在学语言?不,它在重新发明语言学 – 人人都是产品经理 所谓Skill,不过是AI时代的工业垃圾 – 人人都是产品经理, 聊一聊内容传播的几个方法 – 人人都是产品经理, 当平台开始吃掉生态:从 OpenClaw 被封杀,读懂 Anthropic 的这盘棋 – 人人都是产品经理, 你装了 10 个 AI 插件,Obsidian 还是一个文件夹 – 人人都是产品经理 关于AI智能体架构演进的系统性思考:从单体试水到多体协同的重构 – 人人都是产品经理, 当“人”变成Skill,我们又该何去何从? – 人人都是产品经理 Mythos 事件:前沿 AI 治理的意外实验 – 人人都是产品经理, 货代CRM:信用与风险管理怎么做,才能把坏账风险拦在放货之前? – 人人都是产品经理, 从HR收集自拍照到员工自助录入——我见证了园区人脸识别从”不可用”到”真好用”的全过程 – 人人都是产品经理 千问闯关AI混沌期:阿里画靶,吴嘉张弓,马云射箭? – 人人都是产品经理,
鸿蒙文件预览开发实践:从打开文件到加速感知
纯爱掌门人 · 2026-06-03 · via 人人都是产品经理

引言

在很多应用场景中,用户需要快速查看一个文件的内容——可能是一份文档、一张图片、一段视频,或者一个纯文本文件。用户的预期很简单:点一下就能看,不需要专门打开另一个编辑器。

鸿蒙的 Preview Kit 提供的就是这种能力。它以拉起新窗口的方式展示文件内容,界面统一、使用简单,开发者不需要自己去实现各类文件格式的渲染逻辑。此外,从 5.0.5(17) 版本开始,Preview Kit 还引入了文件预加载状态感知的能力,让浏览器等下载类应用可以提前感知文件是否已被系统预加载,从而给用户更明确的”加速打开”提示。

本文面向有一定鸿蒙开发基础的开发者,梳理 Preview Kit 的使用方式、开发流程中的关键环节,以及文件预加载状态感知的接入方法。


一、Preview Kit 能做什么,不能做什么

在动手之前,先厘清 Preview Kit 当前的能力边界,避免走弯路。

能做的事:

  • 拉起一个独立的预览窗口,以统一的界面展示文件内容。
  • 支持图片、视频、音频、文本、HTML 等常见文件类型的预览。
  • Office 类文档(如 .docx、.xlsx 等)借助 WPS 的能力来渲染,所以预览界面中会出现”WPS 提供技术支持”等字样——这是正常的。
  • 支持单文件预览和多文件预览(多文件仅限移动端)。
  • 预览窗口是单例的,同一时间只会存在一个。

当前的限制:

  • 只支持跳出应用预览,暂不支持在应用内嵌入预览视图。如果你想在应用页面里直接内嵌一个文件预览区域,目前 Preview Kit 还做不到。
  • 没有安全定制能力。禁止截录屏、屏蔽”使用其他应用打开”、屏蔽分享入口等安全相关的控制,暂时都不支持。
  • 需要文件的访问权限。调用方必须具备对应 URI 的转授权能力,让预览窗口能正常读取文件内容。这一点在实际开发中容易踩坑,如果预览时报错,优先检查权限问题。

二、文件预览的完整开发流程

Preview Kit 的使用流程可以归纳为:判断能否预览 → 打开预览 → (可选)切换文件 → (可选)关闭预览。下面逐步展开。

2.1 导入模块

import { filePreview } from '@kit.PreviewKit';
import { BusinessError } from '@kit.BasicServicesKit';

filePreview 是 Preview Kit 的核心模块,BusinessError 用于错误处理。

2.2 先判断文件能不能预览

在正式打开预览之前,最好先检查一下目标文件是否支持预览。这一步不是必须的,但可以帮你在 UI 层做更好的引导——比如对不支持预览的文件,显示”不支持预览”的提示而不是让用户点了没反应。

let uri = 'file://docs/storage/Users/currentUser/Documents/1.txt';
let uiContext = this.getUIContext().getHostContext() as Context;

filePreview.canPreview(uiContext, uri).then((result) => {
  console.info(`是否可预览: ${result}`);
}).catch((err: BusinessError) => {
  console.error(`判断失败, err.code = ${err.code}, err.message = ${err.message}`);
});

当传入的文件类型在支持范围内(图片、视频、音频、文本、HTML)且文件确实存在时,返回 true;否则返回 false

2.3 打开预览窗口

这是最核心的一步。Preview Kit 提供了两种异步调用风格——Promise 和 Callback,功能完全一样,选择你习惯的即可。

Promise 方式:

let uiContext = this.getUIContext().getHostContext() as Context;

let displayInfo: filePreview.DisplayInfo = {
  x: 100, y: 100,
  width: 800, height: 800
};

let fileInfo: filePreview.PreviewInfo = {
  title: '1.txt',
  uri: 'file://docs/storage/Users/currentUser/Documents/1.txt',
  mimeType: 'text/plain'
};

filePreview.openPreview(uiContext, fileInfo, displayInfo).then(() => {
  console.info('预览打开成功');
}).catch((err: BusinessError) => {
  console.error(`打开失败, err.code = ${err.code}, err.message = ${err.message}`);
});

这里有几个关键参数需要说明:

  • PreviewInfo:描述要预览的文件,包含标题(title)、文件路径(uri)和 MIME 类型(mimeType)。MIME 类型告诉系统这是什么格式的文件,以便选择正确的渲染方式。
  • DisplayInfo:控制预览窗口的位置和大小,包括 x/y 坐标以及宽高。

有一个细节值得注意:1 秒内重复调用 openPreview 是无效的。这是为了防止用户快速连续点击导致重复打开窗口,开发者不需要自己加防抖逻辑。

Callback 方式:

filePreview.openPreview(uiContext, fileInfo, displayInfo, (err) => {
  if (err && err.code) {
    console.error(`打开失败, err.code = ${err.code}, err.message = ${err.message}`);
    return;
  }
  console.info('预览打开成功');
});

2.4 一次预览多个文件(仅移动端)

在移动端场景下,你可以一次传入多个文件,用户可以在预览窗口中左右滑动切换。传入时通过 index 参数指定默认展示第几个文件(从 0 开始):

let files: Array<filePreview.PreviewInfo> = [];

files.push({
  title: '1.txt',
  uri: 'file://docs/storage/Users/currentUser/Documents/1.txt',
  mimeType: 'text/plain'
});

files.push({
  title: '2.txt',
  uri: 'file://docs/storage/Users/currentUser/Documents/2.txt',
  mimeType: 'text/plain'
});

filePreview.openPreview(uiContext, files, 0).then(() => {
  console.info('多文件预览打开成功');
}).catch((err: BusinessError) => {
  console.error(`打开失败, err.code = ${err.code}, err.message = ${err.message}`);
});

这个能力比较适合文件管理器、聊天应用中查看多张图片等场景。

2.5 在已有窗口中切换文件

如果预览窗口已经打开了,你不需要关闭再重新打开来展示另一个文件。loadData 方法可以直接在当前窗口中加载新的文件内容:

let newFile: filePreview.PreviewInfo = {
  title: '2.txt',
  uri: 'file://docs/storage/Users/currentUser/Documents/2.txt',
  mimeType: 'text/plain'
};

filePreview.loadData(uiContext, newFile).then(() => {
  console.info('文件加载成功');
}).catch((err: BusinessError) => {
  console.error(`加载失败, err.code = ${err.code}, err.message = ${err.message}`);
});

需要注意的是,loadData 只在预览窗口已经存在时才生效,而且 100 毫秒内重复调用无效(比 openPreview 的 1 秒限制更短,因为切换文件的操作相对轻量)。如果传入的文件不支持预览,窗口会显示”不支持预览”的界面,而不是报错。

2.6 关闭预览窗口

filePreview.closePreview(uiContext).then(() => {
  console.info('预览窗口已关闭');
}).catch((err: BusinessError) => {
  console.error(`关闭失败, err.code = ${err.code}, err.message = ${err.message}`);
});

同样只在预览窗口存在时生效。另外,你还可以通过 hasDisplayed 方法来判断预览窗口当前是否处于打开状态,在一些需要条件判断的逻辑中会比较有用。


三、文件预加载状态感知:让”秒开”看得见

从 5.0.5(17) 版本开始,Preview Kit 新增了一项面向特定场景的能力——文件预加载状态感知。这个功能目前仅在 2in1 设备上支持,典型的使用者是浏览器等支持下载文件的应用。

3.1 这项能力解决什么问题

系统有时会对用户可能打开的文件进行预加载,也就是提前把文件内容读入缓存,让后续打开更快。但问题在于,用户并不知道哪些文件已经被预加载了。如果应用能感知到某个文件的预加载状态,就可以在 UI 上给用户一个明确的提示——比如一个”闪电”图标表示”这个文件可以秒开”,体验上会好很多。

3.2 三种预加载状态

一个文件的预加载状态有三种:

状态 含义 建议的 UI 处理
PRELOADING 正在预加载中 可以显示加载动画
PRELOADED 预加载已完成 提示用户”加速打开”已就绪
NOT_PRELOADED 没有预加载 不需要额外提示

3.3 开发流程

整个接入过程分为四步:注册回调 → 添加文件监听 → 响应状态变化 → 清理资源。

第一步,导入模块并注册回调:

import { openFileBoost } from '@kit.PreviewKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

function callback(info: openFileBoost.FilePreloadStatusInfo): void {
  if (info.state === openFileBoost.FilePreloadState.PRELOADING) {
    hilog.info(0x0000, 'testTag', '文件正在预加载,可以展示加载动画');
  }
  if (info.state === openFileBoost.FilePreloadState.PRELOADED) {
    hilog.info(0x0000, 'testTag', '预加载完成,可以提示用户加速打开');
  }
  if (info.state === openFileBoost.FilePreloadState.NOT_PRELOADED) {
    hilog.info(0x0000, 'testTag', '未预加载,无需额外提示');
  }
}

// 注册监听
openFileBoost.on('filePreloadStateChanged', callback);

第二步,添加需要监听的文件:

注册回调之后,通过 addFile 传入文件的沙箱路径。之后这个文件的预加载状态一旦变化,就会通过上面注册的回调通知你。

const file = "/storage/Users/currentUser/Desktop/10MB_file.docx";
openFileBoost.addFile(file);

一个典型场景是:用户通过浏览器下载了一个文件,下载完成后,应用将该文件路径注册进来,后续如果系统对其进行了预加载,应用就能及时在下载列表中标记出来。

这里有一个限制需要注意:单个应用最多同时监听 50 个文件。不再需要关注的文件,应该及时调用 removeFile 取消监听,把名额腾出来:

openFileBoost.removeFile(file);

第三步,主动查询预加载状态:

除了被动等回调,你也可以主动查询某个文件当前的预加载状态。这在应用刚启动时特别有用——可以遍历一遍关心的文件,把已经预加载完成的标记出来:

let statusInfo = openFileBoost.queryFilePreloadStatusInfo(file);
hilog.info(0x0000, 'testTag',
  `文件: ${statusInfo.sandboxPath}, 进度: ${statusInfo.progress}, 状态: ${statusInfo.state}`);

返回的 FilePreloadStatusInfo 不仅包含状态,还有加载进度信息,可以用于更细粒度的 UI 展示。

第四步,清理资源:

当不再需要监听任何文件的预加载状态时,注销回调。off 方法支持两种用法:传入具体的回调函数则只取消该函数的监听,不传参数则取消当前进程的所有回调。

// 只取消某一个回调
openFileBoost.off('filePreloadStateChanged', callback);

// 取消所有回调
openFileBoost.off('filePreloadStateChanged');

3.4 接入前的准备

因为这项能力目前仅在 2in1 设备上可用,在接入之前,建议先通过 Syscap 查询目标设备是否支持 SystemCapability.PCService.OpenFileBoost。对于不支持的设备类型(如手机、平板),不需要也不应该调用这些接口。

另外,当前支持预加载的文件类型是有限的,不在支持范围内的文件类型默认为”未预加载”状态,不需要额外注册监听。


四、总结与实践建议

Preview Kit 的两项能力——文件预览和预加载状态感知——分别解决的是”怎么看文件”和”怎么更快地看文件”的问题。

对于文件预览,开发者要抓住几个要点:

  1. 权限先行。预览的前提是文件可被访问,URI 的转授权是最常见的问题来源。
  2. 善用 canPreview 做前置判断。在 UI 层提前给用户预期,好过让用户点击后看到失败。
  3. 预览窗口是单例的。不需要担心重复打开的问题,但切换文件时记得用 loadData 而不是重新调用 openPreview
  4. 留意调用频率限制openPreview 有 1 秒的防重复机制,loadData 是 100 毫秒。

对于预加载状态感知,如果你的应用运行在 2in1 设备上且涉及文件下载或管理,这是一个值得接入的体验增强点。用户能直观看到哪些文件可以”秒开”,点击的信心和满意度都会更高。接入时注意控制监听文件数量(上限 50 个),及时清理不再需要的监听,保持资源使用的整洁。