<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>LueChan</title>
        <link>https://www.luechan.com/</link>
        <description>HarmonyOS Developer</description>
        <lastBuildDate>Sun, 16 Jun 2024 10:41:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2024, NotionNext</copyright>
        <item>
            <title><![CDATA[其他：一多]]></title>
            <link>https://www.luechan.com/article/one-more</link>
            <guid>https://www.luechan.com/article/one-more</guid>
            <pubDate>Fri, 15 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[一次开发，多端部署]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-5d97985e959b462394e39d8f2174efc9"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-a02def3557164c5a998c74f8303746c1" data-id="a02def3557164c5a998c74f8303746c1"><span><div id="a02def3557164c5a998c74f8303746c1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a02def3557164c5a998c74f8303746c1" title="概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>概述</b></span></span></h2><div class="notion-text notion-block-1d3b1fda99b34478a6add99dad447e7e">随着终端设备形态日益多样化，一个应用或服务，需要在不同的硬件设备之间调用，让用户体验无缝的全场景体验。HarmonyOS 系统面向多终端提供了“一次开发，多端部署”（后文中简称为“一多”）的能力，让开发者可以基于一种设计，高效构建多端可运行的应用。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b276d1d4ae584d55b2ec2ef68680bd4e" data-id="b276d1d4ae584d55b2ec2ef68680bd4e"><span><div id="b276d1d4ae584d55b2ec2ef68680bd4e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b276d1d4ae584d55b2ec2ef68680bd4e" title="定义和目标"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>定义和目标</b></span></span></h4><div class="notion-text notion-block-df596f1288d6417a96a288687d9b8bea">定义：一套代码工程，一次开发上架，多端按需部署。</div><div class="notion-text notion-block-8f2b6d62d7ac472a80aafca86f5f5161">目标：支撑开发者快速高效的开发支持多种终端设备形态的应用，实现对不同设备兼容的同时，提供跨设备的流转、迁移和协同的分布式体验。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c4d433b980b443e0bbf55ad473b1cb8f" data-id="c4d433b980b443e0bbf55ad473b1cb8f"><span><div id="c4d433b980b443e0bbf55ad473b1cb8f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c4d433b980b443e0bbf55ad473b1cb8f" title="关键问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>关键问题</b></span></span></h4><div class="notion-text notion-block-f2231c09ffe245f6a0492e43b6fbf5cb">为了实现“一多”的目标，需要解决如下三个基础问题：</div><div class="notion-text notion-block-e84ac0ac92274f549e4b186b24140173"><b>问题1：页面如何适配</b></div><div class="notion-text notion-block-04287d1f3420494291ce35dc89d63c3e">不同设备间的屏幕尺寸、色彩风格等存在差异，页面如何适配。</div><div class="notion-text notion-block-f26442e5ac5941a1b50a6da12e4c8181"><b>问题2：功能如何兼容</b></div><div class="notion-text notion-block-7992e6ca93fe4410b8d0f928cfe0257b">不同设备的系统能力有差异，如智能穿戴设备是否具备定位能力、智慧屏是否具备摄像头等，功能如何兼容。</div><div class="notion-text notion-block-fd9d0e29e2bc4a34bec79fcaf2c3e25f"><b>问题3：工程如何组织</b></div><div class="notion-text notion-block-04c0fe4a8bea410994a3b5eafb55ccc1">如何实现一套代码同时能部署到多种不同设备上，代码工程如何组织。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-350ad498050548dfa1d9cfc26bf7e076" data-id="350ad498050548dfa1d9cfc26bf7e076"><span><div id="350ad498050548dfa1d9cfc26bf7e076" class="notion-header-anchor"></div><a class="notion-hash-link" href="#350ad498050548dfa1d9cfc26bf7e076" title="关键问题的解决思路"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>关键问题的解决思路</b></span></span></h4><div class="notion-text notion-block-39d837b564d54ca98f32b9d0559628ee">针对“一多”提出的三个基础问题，可以从界面级、功能级、工程级三个维度给出相关问题的解决思路：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4aa673a5d440409bbee0c098faeeafa3"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:700px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240201110417.78735267311752076522988525609653:50001231000000:2800:9E70AFE84412F06BBBEEEF75F33D6B0D617DDF975A0CA0C42551ABC2EB51CEA3.png?needInitFileName=true?needInitFileName=true&amp;t=4aa673a5-d440-409b-bee0-c098faeeafa3" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-769e07d8a82744298462927f87b4a253" data-id="769e07d8a82744298462927f87b4a253"><span><div id="769e07d8a82744298462927f87b4a253" class="notion-header-anchor"></div><a class="notion-hash-link" href="#769e07d8a82744298462927f87b4a253" title="界面级一多"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>界面级一多</b></span></span></h2><div class="notion-text notion-block-43feb547a9234085abc4e07e49bc8c32">页面级一多需要考虑不同设备间的屏幕尺寸、色彩风格等存在差异，页面如何适配。可以从布局能力、资源使用、交互归一几个方面去考虑。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e69c5486984c440099d60428ed209156" data-id="e69c5486984c440099d60428ed209156"><span><div id="e69c5486984c440099d60428ed209156" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e69c5486984c440099d60428ed209156" title="布局能力"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>布局能力</b></span></span></h4><div class="notion-text notion-block-89f3b36877c644f9a4336446b24b7946">布局决定了页面中的元素按照何种方式排布及显示，是页面设计及开发过程中首先需要考虑的问题。一般情况下，可以通过页面（或自定义组件）内的组件结构（组件个数、组件的父子/兄弟关系、组件类型、组件的相对位置）来判断使用何种布局能力。</div><ul class="notion-list notion-list-disc notion-block-339505b002c744fcba26f5788259ddf5"><li>对于随尺寸变化组件结构相同的场景，可以在开发过程中灵活使用自适应布局能力来达到目标效果。</li></ul><ul class="notion-list notion-list-disc notion-block-56bf44d9db674640902cfe0cf6771004"><li>对于随尺寸变化组件结构不同的场景，更适合使用响应式布局能力来实现不同尺寸下的不同显示的效果。</li></ul><div class="notion-text notion-block-af0ca3b856c2430fb1c7b6558e1fc86c">布局可以分为自适应布局和响应式布局，二者的介绍如下表所示：</div><table class="notion-simple-table notion-block-acad76e9d079495b9b663a9db35c8685"><tbody><tr class="notion-simple-table-row notion-block-860077f54e1f4a2aa8eaf7c0d21d36d5"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>名称</b></div></td><td class="" style="width:848px"><div class="notion-simple-table-cell"><b>简介</b></div></td></tr><tr class="notion-simple-table-row notion-block-4bcf6da624d04cb89d56425ae371f886"><td class="" style="width:120px"><div class="notion-simple-table-cell">自适应布局</div></td><td class="" style="width:848px"><div class="notion-simple-table-cell">当外部容器大小发生变化时，元素可以根据相对关系自动变化以适应外部容器变化的布局能力。相对关系如占比、固定宽高比、显示优先级等。当前自适应布局能力有7种：拉伸能力、均分能力、占比能力、缩放能力、延伸能力、隐藏能力、折行能力。自适应布局能力可以实现界面显示随外部容器大小连续变化。</div></td></tr><tr class="notion-simple-table-row notion-block-826aa487658c4da1994f727252a5c248"><td class="" style="width:120px"><div class="notion-simple-table-cell">响应式布局</div></td><td class="" style="width:848px"><div class="notion-simple-table-cell">当外部容器大小发生变化时，元素可以根据断点、栅格或特定的特征（如屏幕方向、窗口宽高等）自动变化以适应外部容器变化的布局能力。当前响应式布局能力有3种：断点、媒体查询、栅格布局。响应式布局可以实现界面随外部容器大小有级不连续变化，通常不同特征下的界面显示会有较大的差异。</div></td></tr></tbody></table><div class="notion-text notion-block-aa50cefd5d5548b1bc3adebd69b664b8"><b>自适应布局</b></div><div class="notion-text notion-block-b77a8fc505b54a168bfe1d999aa19d9b">针对常见的开发场景，方舟开发框架提炼了七种自适应布局能力，这些布局可以独立使用，也可多种布局叠加使用。</div><table class="notion-simple-table notion-block-b8ca21d0a7f645ecba3f296e22549730"><tbody><tr class="notion-simple-table-row notion-block-4e59bdc66b0a4cb1bc4a9e964d10736f"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>自适应布局能力</b></div></td><td class="" style="width:415px"><div class="notion-simple-table-cell"><b>使用场景</b></div></td><td class="" style="width:422px"><div class="notion-simple-table-cell"><b>实现方式</b></div></td></tr><tr class="notion-simple-table-row notion-block-b18f3653e91c4745bb516003c300770c"><td class="" style="width:120px"><div class="notion-simple-table-cell">拉伸能力</div></td><td class="" style="width:415px"><div class="notion-simple-table-cell">容器组件尺寸发生变化时，增加或减小的空间全部分配给容器组件内指定区域。</div></td><td class="" style="width:422px"><div class="notion-simple-table-cell">Flex布局的flexGrow和flexShrink属性</div></td></tr><tr class="notion-simple-table-row notion-block-22c40c8fc6ce440ba91ed60d860a6231"><td class="" style="width:120px"><div class="notion-simple-table-cell">均分能力</div></td><td class="" style="width:415px"><div class="notion-simple-table-cell">容器组件尺寸发生变化时，增加或减小的空间均匀分配给容器组件内所有空白区域。</div></td><td class="" style="width:422px"><div class="notion-simple-table-cell">Row组件、Column组件或Flex组件的justifyContent属性设置为FlexAlign.SpaceEvenly</div></td></tr><tr class="notion-simple-table-row notion-block-ed218322368b4bba92138503531dd54a"><td class="" style="width:120px"><div class="notion-simple-table-cell">占比能力</div></td><td class="" style="width:415px"><div class="notion-simple-table-cell">子组件的宽或高按照预设的比例，随容器组件发生变化。</div></td><td class="" style="width:422px"><div class="notion-simple-table-cell">基于通用属性的两种实现方式：<!-- -->
<!-- -->- 将子组件的宽高设置为父组件宽高的百分比<!-- -->
<!-- -->- layoutWeight属性</div></td></tr><tr class="notion-simple-table-row notion-block-dc531a0c0cdf45baa2347a3df41bd533"><td class="" style="width:120px"><div class="notion-simple-table-cell">缩放能力</div></td><td class="" style="width:415px"><div class="notion-simple-table-cell">子组件的宽高按照预设的比例，随容器组件发生变化，且变化过程中子组件的宽高比不变。</div></td><td class="" style="width:422px"><div class="notion-simple-table-cell">布局约束的aspectRatio属性</div></td></tr><tr class="notion-simple-table-row notion-block-7100f4b58e2343b09cb93657704863b9"><td class="" style="width:120px"><div class="notion-simple-table-cell">延伸能力</div></td><td class="" style="width:415px"><div class="notion-simple-table-cell">容器组件内的子组件，按照其在列表中的先后顺序，随容器组件尺寸变化显示或隐藏。</div></td><td class="" style="width:422px"><div class="notion-simple-table-cell">基于容器组件的两种实现方式：<!-- -->
<!-- -->- 通过List组件实现<!-- -->
<!-- -->- 通过Scroll组件配合Row组件或Column组件实现</div></td></tr><tr class="notion-simple-table-row notion-block-3540c6a325244c789950b4244e082ff7"><td class="" style="width:120px"><div class="notion-simple-table-cell">隐藏能力</div></td><td class="" style="width:415px"><div class="notion-simple-table-cell">容器组件内的子组件，按照其预设的显示优先级，随容器组件尺寸变化显示或隐藏。相同显示优先级的子组件同时显示或隐藏。</div></td><td class="" style="width:422px"><div class="notion-simple-table-cell">布局约束的displayPriority属性</div></td></tr><tr class="notion-simple-table-row notion-block-57c6b374d0854f70bdb14f4a4d7bb92a"><td class="" style="width:120px"><div class="notion-simple-table-cell">折行能力</div></td><td class="" style="width:415px"><div class="notion-simple-table-cell">容器组件尺寸发生变化时，如果布局方向尺寸不足以显示完整内容，自动换行。</div></td><td class="" style="width:422px"><div class="notion-simple-table-cell">Flex组件的wrap属性设置为FlexWrap.Wrap</div></td></tr></tbody></table><div class="notion-text notion-block-834ffb7da896453faaf46473ce29b861"><b>响应式布局</b></div><div class="notion-text notion-block-49af6e78ea5d4b9783819299946435e3">响应式布局是指页面内的元素可以根据特定的特征（如窗口宽度、屏幕方向等）自动变化以适应外部容器变化的布局能力。响应式布局中最常使用的特征是窗口宽度，可以将窗口宽度划分为不同的范围（下文中称为断点）。当窗口宽度从一个断点变化到另一个断点时，改变页面布局（如将页面内容从单列排布调整为双列排布甚至三列排布等）以获得更好的显示效果。</div><table class="notion-simple-table notion-block-da3a777b3cc34957b4a3239f03021758"><tbody><tr class="notion-simple-table-row notion-block-0f0053079b3a437fa12968601a520b30"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>响应式布局能力</b></div></td><td class="" style="width:838px"><div class="notion-simple-table-cell"><b>简介</b></div></td></tr><tr class="notion-simple-table-row notion-block-dc19e26bc78448489e4d21dc9ccf25e0"><td class="" style="width:120px"><div class="notion-simple-table-cell">断点</div></td><td class="" style="width:838px"><div class="notion-simple-table-cell">将窗口宽度划分为不同的范围（即断点），监听窗口尺寸变化，当断点改变时同步调整页面布局。</div></td></tr><tr class="notion-simple-table-row notion-block-961b14dd2a75452393eb98b76f098442"><td class="" style="width:120px"><div class="notion-simple-table-cell">媒体查询</div></td><td class="" style="width:838px"><div class="notion-simple-table-cell">媒体查询支持监听窗口宽度、横竖屏、深浅色、设备类型等多种媒体特征，当媒体特征发生改变时同步调整页面布局。</div></td></tr><tr class="notion-simple-table-row notion-block-c31f000deac8485ba3d0c9792b1f5398"><td class="" style="width:120px"><div class="notion-simple-table-cell">栅格布局</div></td><td class="" style="width:838px"><div class="notion-simple-table-cell">栅格组件将其所在的区域划分为有规律的多列，通过调整不同断点下的栅格组件的参数以及其子组件占据的列数等，实现不同的布局效果。</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8a79c572828141d89a39d8314d72610d" data-id="8a79c572828141d89a39d8314d72610d"><span><div id="8a79c572828141d89a39d8314d72610d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8a79c572828141d89a39d8314d72610d" title="资源使用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>资源使用</b></span></span></h4><div class="notion-text notion-block-0f162484ed64462f9ee517bd23f379c9">在页面开发过程中，经常需要用到颜色、字体、间距、图片等资源，在不同的设备或配置中，这些资源的值可能不同。有两种方式处理：</div><ul class="notion-list notion-list-disc notion-block-64575713c790465ea620220798abaa7d"><li>应用资源：借助资源文件能力，开发者在应用中自定义资源，自行管理这些资源在不同的设备或配置中的表现。</li></ul><ul class="notion-list notion-list-disc notion-block-d0814bf3438e493cb3a6ab4bd7672e1b"><li>系统资源：开发者直接使用系统预置的资源定义（即分层参数）。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b414e5c827824195b46da18fc2377b31" data-id="b414e5c827824195b46da18fc2377b31"><span><div id="b414e5c827824195b46da18fc2377b31" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b414e5c827824195b46da18fc2377b31" title="交互归一"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>交互归一</b></span></span></h4><div class="notion-text notion-block-e1823466f08042a582eb694ab133ef8f">对于不同类型的智能设备，用户可能有不同的交互方式，如通过触摸屏、鼠标、触控板等。如果针对不同的交互方式单独做适配，会增加开发工作量同时产生大量重复代码。为解决这一问题，我们统一了各种交互方式的API，即实现了交互归一。</div><div class="notion-text notion-block-68146cfabfe3496f9968ac0d448f0733">常见的基础输入方式及其在各输入设备上的表现如下图所示。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-70ccd09834c24429843b3aec789927e2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:700px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240201110417.27948927213406269393018010208608:50001231000000:2800:AD101AA91FD1C8C964109E8C61C7F91E99D606F3D99EA0CCACF2E0FDB0155388.png?needInitFileName=true?needInitFileName=true&amp;t=70ccd098-34c2-4429-843b-3aec789927e2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-204fcdddfdd5425cb23b93e57b5d976c" data-id="204fcdddfdd5425cb23b93e57b5d976c"><span><div id="204fcdddfdd5425cb23b93e57b5d976c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#204fcdddfdd5425cb23b93e57b5d976c" title="功能级一多"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>功能级一多</b></span></span></h2><div class="notion-text notion-block-d81171b653f945e993a7b955bbb6330e">应用开发至少包含两部分工作： UI页面开发和底层功能开发（部分需要联网的应用还会涉及服务端开发）。前面章节介绍了如何解决页面适配的问题，本章节主要介绍应用如何解决设备系统能力差异的兼容问题。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-84b00f4768c944079cc462a601e32787" data-id="84b00f4768c944079cc462a601e32787"><span><div id="84b00f4768c944079cc462a601e32787" class="notion-header-anchor"></div><a class="notion-hash-link" href="#84b00f4768c944079cc462a601e32787" title="系统能力"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>系统能力</b></span></span></h4><div class="notion-text notion-block-3767de182fbf4b698f60a644e91a3974">系统能力（即SystemCapability，缩写为SysCap）指操作系统中每一个相对独立的特性，如蓝牙，WIFI，NFC，摄像头等，都是系统能力之一。每个系统能力对应多个API，随着目标设备是否支持该系统能力共同存在或消失。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-7965181a560746a0954c3f1c46f001de"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:641px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240201110417.75125358625859404994963145674735:50001231000000:2800:77A31B26B7E53E4295E7DD1506058A4D588A73136AFA8C60D620CBBA1D0E6C12.png?needInitFileName=true?needInitFileName=true&amp;t=7965181a-5607-46a0-954c-3f1c46f001de" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-6a5f0fa94824461daba74feb8a6833ba">与系统能力相关的，有支持能力集、联想能力集和要求能力集三个核心概念。</div><ul class="notion-list notion-list-disc notion-block-15fd3f59368d4a9eb0534daf2be613a3"><li>支持能力集：设备具备的系统能力集合，在设备配置文件中配置。</li></ul><ul class="notion-list notion-list-disc notion-block-8a8ad15687e04634987b837017b87841"><li>要求能力集：应用需要的系统能力集合，在应用配置文件中配置。</li></ul><ul class="notion-list notion-list-disc notion-block-ff414e4718a3418396919c871103ad82"><li>联想能力集：开发应用时IDE可联想的API所在的系统能力集合，在应用配置文件中配置。</li></ul><div class="notion-text notion-block-27c7623d04d9433584b9548e9bffe3d4"><b>说明</b></div><ul class="notion-list notion-list-disc notion-block-4b174e55626649729ca4f13291cb8867"><li>只有当应用要求能力集是设备支持能力集的子集的时候，应用才可以在该设备上分发、安装和运行。</li></ul><ul class="notion-list notion-list-disc notion-block-35952aa69546420481360e8f9de0009c"><li>可以访问<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/syscap-list-0000001657953797">系统能力列表</a>了解全量的系统能力。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d4bd4eec9a034c10bb5be182ab971f8a" data-id="d4bd4eec9a034c10bb5be182ab971f8a"><span><div id="d4bd4eec9a034c10bb5be182ab971f8a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d4bd4eec9a034c10bb5be182ab971f8a" title="动态逻辑判断"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>动态逻辑判断</b></span></span></h4><div class="notion-text notion-block-bcf0924327284d6488fe813094723e72">如果某个系统能力没有写入应用的要求能力集中，那么在使用前需要判断设备是否支持该系统能力。</div><ul class="notion-list notion-list-disc notion-block-1e7f84b4063f4f44beffd3689335434e"><li>方法1：HarmonyOS定义了API canIUse帮助开发者来判断该设备是否支持某个特定的syscap。</li></ul><ul class="notion-list notion-list-disc notion-block-23cb9329e57440e6a3a3244f48c92448"><li>方法2：开发者可通过import的方式将模块导入，若当前设备不支持该模块，import的结果为undefined，开发者在使用其API时，需要判断其是否存在。</li></ul><div class="notion-callout notion-gray_background_co notion-block-b3754a4bdf51433d95b03978d99a86c1"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text"><b>说明</b><ul class="notion-list notion-list-disc notion-block-45354fd68f574ef297b2e09e4edfb8c4"><li>如果某系统能力是应用运行必须的，则要将其写入到应用的要求能力集中，以确保应用不会分发和安装到不符合要求的设备上。</li></ul><ul class="notion-list notion-list-disc notion-block-ad527f8fcee74732a8f2115d0e9928ec"><li>如果某系统能力不是应用运行必须的，则可以在运行时做动态判断，这样可以最大程度扩大应用的适用范围。</li></ul></div></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-15daf6d211464135af4e370532f3ef90" data-id="15daf6d211464135af4e370532f3ef90"><span><div id="15daf6d211464135af4e370532f3ef90" class="notion-header-anchor"></div><a class="notion-hash-link" href="#15daf6d211464135af4e370532f3ef90" title="配置联想能力集和要求能力集"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>配置联想能力集和要求能力集</b></span></span></h4><ul class="notion-list notion-list-disc notion-block-eb80197110164b16b28078ac7c01bdda"><li>IDE会根据创建的工程所支持的设备自动配置联想能力集和要求能力集，同时也支持开发者修改。</li></ul><div class="notion-callout notion-gray_background_co notion-block-fbae8ccb910e43e1ae71714d8563a20b"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text"><b>说明</b><ul class="notion-list notion-list-disc notion-block-aa6df77a3a404f3da22c9dc7f1d3f880"><li>对于要求能力集，开发者修改时要十分慎重，修改不当会导致应用无法分发和安装到目标设备上。</li></ul><ul class="notion-list notion-list-disc notion-block-d1b126aba73e487789e1a7a17b79a8ea"><li>对于联想能力集，通过增加系统能力可以扩大IDE可联想的API范围。但要注意这些API可能在某些设备上不支持，使用前需要判断。</li></ul></div></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-cb8e194106ba4662b9f5c3722ab648dc" data-id="cb8e194106ba4662b9f5c3722ab648dc"><span><div id="cb8e194106ba4662b9f5c3722ab648dc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cb8e194106ba4662b9f5c3722ab648dc" title="工程级一多"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>工程级一多</b></span></span></h2><div class="notion-text notion-block-7e112957f6264f9484973b76fc21bcbf">工程级一多需要考虑如何实现一套代码同时能部署到多种不同设备上，代码工程如何组织。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-4e978d049fc340888298096c7080b438" data-id="4e978d049fc340888298096c7080b438"><span><div id="4e978d049fc340888298096c7080b438" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4e978d049fc340888298096c7080b438" title="应用程序包结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>应用程序包结构</b></span></span></h4><div class="notion-text notion-block-c31f8bd98d63499a9a167a87a93661e2">在进行应用开发时，一个应用通常包含一个或多个Module。Module是HarmonyOS应用/服务的基本功能单元，包含了源代码、资源文件、第三方库及应用/服务配置文件，每一个Module都可以独立进行编译和运行。</div><div class="notion-text notion-block-f16c37727edf481996fff7a1a5aa4b51">Module分为“Ability”和“Library”两种类型：</div><ul class="notion-list notion-list-disc notion-block-cb9058fbc40e4ea0bc7753993c6b51d9"><li>“Ability”类型的Module编译后生成HAP包。</li></ul><ul class="notion-list notion-list-disc notion-block-5c175a3a771349db80bc5ef0609bbb19"><li>“Library”类型的Module编译后生成HAR包。</li></ul><div class="notion-text notion-block-631a1bf321f34964a01a15bc349b2ba8">HarmonyOS的应用以APP Pack形式发布，其包含一个或多个HAP包。HAP是HarmonyOS应用安装的基本单位，HAP可以分为Entry和Feature两种类型：</div><ul class="notion-list notion-list-disc notion-block-be48980c35bf492c91c1434989719541"><li>Entry类型的HAP：应用的主模块。在同一个应用中，同一设备类型只支持一个Entry类型的HAP，通常用于实现应用的入口界面、入口图标、主特性功能等。</li></ul><ul class="notion-list notion-list-disc notion-block-c70ff30bfe034d34b822476842548ae8"><li>Feature类型的HAP：应用的动态特性模块。Feature类型的HAP通常用于实现应用的特性功能，一个应用程序包可以包含一个或多个Feature类型的HAP，也可以不包含。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5a88eaf2c2d44e689557ea94bfda18c6" data-id="5a88eaf2c2d44e689557ea94bfda18c6"><span><div id="5a88eaf2c2d44e689557ea94bfda18c6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5a88eaf2c2d44e689557ea94bfda18c6" title="部署模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>部署模型</b></span></span></h4><div class="notion-text notion-block-7dddbe4a63934f25ada81cbe54ae4bc6">“一多”有两种部署模型：</div><ul class="notion-list notion-list-disc notion-block-ee5564a2c88445348e52713378030cd9"><li>部署模型A：不同类型的设备上按照一定的工程结构组织方式，通过一次编译生成相同的HAP（或HAP组合）。</li></ul><ul class="notion-list notion-list-disc notion-block-14656b1dd3db420e94515c86015bbb83"><li>部署模型B：不同类型的设备上按照一定的工程结构组织方式，通过一次编译生成不同的HAP（或HAP组合）。</li></ul><div class="notion-text notion-block-d992a0e8d830483f9446472ee37016a4">开发者可以从应用UX设计及应用功能两个维度，结合具体的业务场景，考虑选择哪种部署模型。当然，也可以借助设备类型分类，快速做出判断。</div><div class="notion-text notion-block-52639890e9034e17b1227ac2135189b0">从屏幕尺寸、输入方式及交互距离三个维度考虑，可以将常用类型的设备分为不同泛类：</div><ul class="notion-list notion-list-disc notion-block-0bc28aea2eae4104b5f29433e66fe91a"><li>默认设备、平板</li></ul><ul class="notion-list notion-list-disc notion-block-4645541e90c642069c1ea8a592883afd"><li>车机、智慧屏</li></ul><ul class="notion-list notion-list-disc notion-block-9d7dde2cec1a492999bc615c39ad98c4"><li>智能穿戴</li></ul><ul class="notion-list notion-list-disc notion-block-dd5e0ba0f01d489da312626acdc7abe0"><li>……</li></ul><div class="notion-text notion-block-0541e7f5584346ce85ddad77609b95c8">对于相同泛类的设备，优先选择部署模型A，对于不同泛类设备，优先选择部署模型B。</div><div class="notion-text notion-block-691e6a8a0bd84f63bb860a2f99424893"><b>说明</b></div><ul class="notion-list notion-list-disc notion-block-6c842b22e5f4487f89b61eef918926d3"><li>应用在不同泛类设备上的UX设计或功能相似时，可以使用部署模型A。</li></ul><ul class="notion-list notion-list-disc notion-block-a182b23cae034865a30ff27854668260"><li>应用在同一泛类不同类型设备上UX设计或功能差异非常大时，可以使用部署模型B，但同时也应审视应用的UX设计及功能规划是否合理。</li></ul><ul class="notion-list notion-list-disc notion-block-c55c8ae87a73464facd89d5c889ee18c"><li>本小节引入部署模型A和部署模型B的概念是为了方便开发者理解。实际上在开发多设备应用时，如果目标设备类型较多，往往是部署模型A和部署模型B混合使用。</li></ul><ul class="notion-list notion-list-disc notion-block-8692a5d643d84e3b83d95ac176328a00"><li>不管采用哪种部署模型，都应该采用一次编译。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-48f13c371430464bbce9c3fe39bdecec" data-id="48f13c371430464bbce9c3fe39bdecec"><span><div id="48f13c371430464bbce9c3fe39bdecec" class="notion-header-anchor"></div><a class="notion-hash-link" href="#48f13c371430464bbce9c3fe39bdecec" title="工程结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>工程结构</b></span></span></h4><div class="notion-text notion-block-7287ec9ac1e54ad2ab6d4c8b06261565">“一多”推荐在应用开发过程中使用如下的“三层工程结构”。</div><ul class="notion-list notion-list-disc notion-block-c6618e1c72544d129d405341b5a01a17"><li>common（公共能力层）：用于存放公共基础能力集合（如工具库、公共配置等）。</li><ul class="notion-list notion-list-disc notion-block-c6618e1c72544d129d405341b5a01a17"><div class="notion-text notion-block-a395c5ab4f454b68aa5da36a34934172">common层不可分割，需编译成一个HAR包，其只可以被products和features依赖，不可以反向依赖。</div></ul></ul><ul class="notion-list notion-list-disc notion-block-210b53a467b24840bf0f22b29b406333"><li>features（基础特性层）：用于存放基础特性集合（如应用中相对独立的各个功能的UI及业务逻辑实现等）。</li><ul class="notion-list notion-list-disc notion-block-210b53a467b24840bf0f22b29b406333"><div class="notion-text notion-block-ee801de41c4146cdb851155e38ae1d4b">各个feature高内聚、低耦合、可定制，供产品灵活部署。不需要单独部署的feature通常编译为HAR包，供products或其它feature使用。需要单独部署的feature通常编译为Feature类型的HAP包，和products下Entry类型的HAP包进行组合部署。features层可以横向调用及依赖common层，同时可以被products层不同设备形态的HAP所依赖，但是不能反向依赖products层。</div></ul></ul><ul class="notion-list notion-list-disc notion-block-86b1f0c864a44d6d99af01c70d97827c"><li>products（产品定制层）：用于针对不同设备形态进行功能和特性集成。</li><ul class="notion-list notion-list-disc notion-block-86b1f0c864a44d6d99af01c70d97827c"><div class="notion-text notion-block-77c2bd18251b48688bee03a719a59f10">products层各个子目录各自编译为一个Entry类型的HAP包，作为应用主入口。products层不可以横向调用。</div></ul></ul><div class="notion-text notion-block-e47d018eb0ae4e31b88ecc9035d5bfff">代码工程结构抽象后一般如下所示：</div><div class="notion-callout notion-gray_background_co notion-block-fa856f5d028c4d72ad0404befc108f66"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text"><b>说明</b><ul class="notion-list notion-list-disc notion-block-6e49241d5ac44abda58180253d0d94b5"><li>部署模型不同，相应的代码工程结构也有差异。部署模型A和部署模型B的主要差异点集中在products层：部署模型A在products目录下同一子目录中做功能和特性集成；部署模型B在products目录下不同子目录中对不同的产品做差异化的功能和特性集成。</li></ul><ul class="notion-list notion-list-disc notion-block-986d4f49d5eb484f978167fcde26a6cb"><li>开发阶段应考虑不同类型设备间最大程度的复用代码，以减少开发及后续维护的工作量。</li></ul><ul class="notion-list notion-list-disc notion-block-84b9cbb66ebf477a822a59b8309f1be4"><li>整个代码工程最终构建出一个APP包，应用以APP包的形式发布到应用市场中。</li></ul></div></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ecab6cc552cd4096b33da89afcc132b7" data-id="ecab6cc552cd4096b33da89afcc132b7"><span><div id="ecab6cc552cd4096b33da89afcc132b7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ecab6cc552cd4096b33da89afcc132b7" title="参考链接"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>参考链接</b></span></span></h2><div class="notion-text notion-block-0558fb8498124d539719a21a3f39dbb7">“一次开发，多端部署”的<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/00_u6b21_u5f00_u53d1_uff0c_u591a_u7aef_u90e8_u7f72-0000001774280426">参考指南</a>中详细讲解了一多的相关知识、UX设计、架构规范等，可供开发者参考。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[其他：应用程序包结构]]></title>
            <link>https://www.luechan.com/article/app-structure</link>
            <guid>https://www.luechan.com/article/app-structure</guid>
            <pubDate>Sun, 25 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[应用包结构]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-958b2d9a17bc4e4c84fb60b97420f987"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-436825847e154710bd67a0e75e4f6a44">为了让开发者能对应用程序包在不同阶段的形态更有清晰的认知，分别对开发态、编译态、发布态的应用程序结构展开介绍。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-cc3e130bb54242768b965a86796060b9" data-id="cc3e130bb54242768b965a86796060b9"><span><div id="cc3e130bb54242768b965a86796060b9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cc3e130bb54242768b965a86796060b9" title="开发态包结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>开发态包结构</b></span></span></h2><div class="notion-text notion-block-7763038f46cd4f16b1438cf45d4995e5">在DevEco Studio上<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/start-with-ets-stage-0000001820879533#ZH-CN_TOPIC_0000001820879533__%E5%88%9B%E5%BB%BAarkts%E5%B7%A5%E7%A8%8B">创建一个项目工程</a>，并尝试创建多个不同类型的Module。根据实际工程中的目录对照本章节进行学习，可以有助于理解开发态的应用程序结构。</div><div class="notion-text notion-block-2c40871d994648dc8d1a8183901f416a"><b>图1</b> 项目工程结构示意图（以实际为准）</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-daee6ad8183543ad90456ab965950d1d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:327px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240313113838.77155212128742777532395912391054:50001231000000:2800:7AA1B62CE2C5D46DCE7245EA0FC927A7CB5A0932F2E04B613EA3838B9F2B5526.png?needInitFileName=true?needInitFileName=true&amp;t=daee6ad8-1835-43ad-9045-6ab965950d1d" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-07b43f35c1d24bbeb19aa9d2b0b35669">工程结构主要包含的文件类型及用途如下：</div><div class="notion-text notion-block-af5d6647f2084d5f9f700cb89934bafb"><b>说明</b></div><ul class="notion-list notion-list-disc notion-block-9fb7448f22f54cb68ab74def6512fed0"><li>AppScope目录由DevEco Studio自动生成，不可更改。</li></ul><ul class="notion-list notion-list-disc notion-block-c91ae8ecc65d453587b2afa2f3c0368a"><li>Module目录名称可以由DevEco Studio自动生成（比如entry、library等），也可以自定义。为了便于说明，下表中统一采用Module_name表示。</li></ul><table class="notion-simple-table notion-block-bfb14caffe404cd784f76ec11e7073d6"><tbody><tr class="notion-simple-table-row notion-block-9bfd811342c946b2acb194a1fb6e1adf"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>文件类型</b></div></td><td class="" style="width:964px"><div class="notion-simple-table-cell"><b>说明</b></div></td></tr><tr class="notion-simple-table-row notion-block-4e8acaa9b0e84d94aeb33d502e520047"><td class="" style="width:120px"><div class="notion-simple-table-cell">配置文件</div></td><td class="" style="width:964px"><div class="notion-simple-table-cell">包括应用级配置信息、以及Module级配置信息：<!-- -->
<!-- -->- <b>AppScope &gt; app.json5</b>：<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-configuration-file-0000001820999529">app.json5配置文件</a>，用于声明应用的全局配置信息，比如应用Bundle名称、应用名称、应用图标、应用版本号等。<!-- -->
<!-- -->- <b>Module_name &gt; src &gt; main &gt; module.json5</b>：<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file-0000001820879553">module.json5配置文件</a>，用于声明Module基本信息、支持的设备类型、所含的组件信息、运行所需申请的权限等。</div></td></tr><tr class="notion-simple-table-row notion-block-13a32f23cdb0458c9611d80df37b49b8"><td class="" style="width:120px"><div class="notion-simple-table-cell">ArkTS源码文件</div></td><td class="" style="width:964px"><div class="notion-simple-table-cell"><b>Module_name &gt; src &gt; main &gt; ets</b>：用于存放Module的ArkTS源码文件（.ets文件）。</div></td></tr><tr class="notion-simple-table-row notion-block-242c9f4bdaa14e4eb202d6a5db52cf02"><td class="" style="width:120px"><div class="notion-simple-table-cell">资源文件</div></td><td class="" style="width:964px"><div class="notion-simple-table-cell">包括应用级资源文件、以及Module级资源文件，支持图形、多媒体、字符串、布局文件等，详见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/resource-categories-and-access-0000001774119914">资源分类与访问</a>。<!-- -->
<!-- -->- <b>AppScope &gt; resources</b> ：用于存放应用需要用到的资源文件。<!-- -->
<!-- -->- <b>Module_name &gt; src &gt; main &gt; resources</b> ：用于存放该Module需要用到的资源文件。</div></td></tr><tr class="notion-simple-table-row notion-block-3c9df1067fc64b84b3004de70f30f8b9"><td class="" style="width:120px"><div class="notion-simple-table-cell">其他配置文件</div></td><td class="" style="width:964px"><div class="notion-simple-table-cell">用于编译构建，包括构建配置文件、编译构建任务脚本、混淆规则文件、依赖的共享包信息等。<!-- -->
<!-- -->- <b>build-profile.json5</b>：工程级或Module级的构建配置文件，包括应用签名、产品配置等。<!-- -->
<!-- -->- <b>hvigorfile.ts</b>：应用级或Module级的编译构建任务脚本，开发者可以自定义编译构建工具版本、控制构建行为的配置参数。<!-- -->
<!-- -->- <b>obfuscation-rules.txt</b>：混淆规则文件。混淆开启后，在使用Release模式进行编译时，会对代码进行编译、混淆及压缩处理，保护代码资产。<!-- -->
<!-- -->- <b>oh-package.json5</b>：用于存放依赖库的信息，包括所依赖的三方库和共享包。</div></td></tr></tbody></table><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-59305af41f4947eeb7fbeeeb15f34d42" data-id="59305af41f4947eeb7fbeeeb15f34d42"><span><div id="59305af41f4947eeb7fbeeeb15f34d42" class="notion-header-anchor"></div><a class="notion-hash-link" href="#59305af41f4947eeb7fbeeeb15f34d42" title="编译态包结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>编译态包结构</b></span></span></h2><div class="notion-text notion-block-a2a9c24692f54614b45b1da713fd05d6">不同类型的Module编译后会生成对应的HAP、HAR、HSP等文件，开发态视图与编译态视图的对照关系如下：</div><div class="notion-text notion-block-4159c29026934d83b59c232dd09ac6eb"><b>图2</b> 开发态与编译态的工程结构视图</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-54b3c1ec284a4531b8c096f6e806bdb3"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:1008px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240313113838.33999813703270836443307426260287:50001231000000:2800:989890F3C86BE47C755684F9BC42ADDA431DA6A63E471F95880DA4B0336D6D2B.png?needInitFileName=true?needInitFileName=true&amp;t=54b3c1ec-284a-4531-b8c0-96f6e806bdb3" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a9bb6235d7e649ba8e6ef62895ce2bd8">从开发态到编译态，Module中的文件会发生如下变更：</div><ul class="notion-list notion-list-disc notion-block-009cb614221147f3aa78c16eb04dcc23"><li><b>ets目录</b>：ArkTS源码编译生成.abc文件。</li></ul><ul class="notion-list notion-list-disc notion-block-f7108a85d22b4ad5889bbcbd8794004e"><li><b>resources目录</b>：AppScope目录下的资源文件会合入到Module下面资源目录中，如果两个目录下的存在重名文件，编译打包后只会保留AppScope目录下的资源文件。</li></ul><ul class="notion-list notion-list-disc notion-block-cda07feda47b471abdd757cffef10995"><li><b>module配置文件</b>：AppScope目录下的app.json5文件字段会合入到Module下面的module.json5文件之中，编译后生成HAP或HSP最终的module.json文件。</li></ul><div class="notion-text notion-block-55c7a4de93a946a39369d766c4c454c0"><b>说明</b></div><div class="notion-text notion-block-4931beaf0d7c4ff68809308aa0a70884">在编译HAP和HSP时，会把他们所依赖的HAR直接编译到HAP和HSP中。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-0d8ce90d040046b8864f1443c527a60d" data-id="0d8ce90d040046b8864f1443c527a60d"><span><div id="0d8ce90d040046b8864f1443c527a60d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0d8ce90d040046b8864f1443c527a60d" title="发布态包结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>发布态包结构</b></span></span></h2><div class="notion-text notion-block-e6dc4ddd16c440a086be240e724e9892">每个应用中至少包含一个.hap文件，可能包含若干个.hsp文件、也可能不含，一个应用中的所有.hap与.hsp文件合在一起称为<b>Bundle</b>，其对应的bundleName是应用的唯一标识（详见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-configuration-file-0000001820999529">app.json5配置文件</a>中的bundleName标签）。</div><div class="notion-text notion-block-52a6d7d48b974d4c8f82221e9645d367">当应用发布上架到应用市场时，需要将Bundle打包为一个.app后缀的文件用于上架，这个.app文件称为<b>App Pack</b>（Application Package），与此同时，DevEco Studio工具自动会生成一个<b>pack.info</b>文件。<b>pack.info</b>文件描述了App Pack中每个HAP和HSP的属性，包含APP中的bundleName和versionCode信息、以及Module中的name、type和abilities等信息。</div><div class="notion-text notion-block-62fbeb50181d45799b5c842df4a26357"><b>说明</b></div><ul class="notion-list notion-list-disc notion-block-fa21a8f556324355a13d3280ae0406c4"><li>App Pack是发布上架到应用市场的基本单元，但是不能在设备上直接安装和运行。</li></ul><ul class="notion-list notion-list-disc notion-block-23527b4cb4d443afae2d8209b2b082bd"><li>在应用签名、云端分发、端侧安装时，都是以HAP/HSP为单位进行签名、分发和安装的。</li></ul><div class="notion-text notion-block-4b1d0c4a983d4f5f878f83b14ed1d7e0"><b>图3</b> 编译发布与上架部署流程图</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-01ff0f0ae5444e51be3821e4d0cb908d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:864px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240313113838.48270468790507645702887692365139:50001231000000:2800:93B4DBFFE22983851721B4FB31612561EA3045D80C81D12DC9005C30F162FE5D.png?needInitFileName=true?needInitFileName=true&amp;t=01ff0f0a-e544-4e51-be38-21e4d0cb908d" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-60fcbc2d9f9c4dd89afec650179cbb33" data-id="60fcbc2d9f9c4dd89afec650179cbb33"><span><div id="60fcbc2d9f9c4dd89afec650179cbb33" class="notion-header-anchor"></div><a class="notion-hash-link" href="#60fcbc2d9f9c4dd89afec650179cbb33" title="选择合适的包类型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>选择合适的包类型</b></span></span></h2><div class="notion-text notion-block-1ed0654419ae4d0d934a3cd8f973fbdc">HAP、HAR、HSP三者的功能和使用场景总结对比如下：</div><table class="notion-simple-table notion-block-5128fb0928494c498a0fdb059734686e"><tbody><tr class="notion-simple-table-row notion-block-0d34008b372543949c114463e2d942d6"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>Module类型</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>包类型</b></div></td><td class="" style="width:800px"><div class="notion-simple-table-cell"><b>说明</b></div></td></tr><tr class="notion-simple-table-row notion-block-9040d673eeb34bb085b72b40df626bdc"><td class="" style="width:120px"><div class="notion-simple-table-cell">Ability</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hap-package-0000001820879541">HAP</a></div></td><td class="" style="width:800px"><div class="notion-simple-table-cell">应用的功能模块，可以独立安装和运行，必须包含一个entry类型的HAP，可选包含一个或多个feature类型的HAP。</div></td></tr><tr class="notion-simple-table-row notion-block-4fab0ec95d5b4527a2ac41d6a9ea0425"><td class="" style="width:120px"><div class="notion-simple-table-cell">Static Library</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/har-package-0000001774279570">HAR</a></div></td><td class="" style="width:800px"><div class="notion-simple-table-cell">静态共享包，编译态复用。<!-- -->
<!-- -->- 支持应用内共享，也可以发布后供其他应用使用。<!-- -->
<!-- -->- 作为二方库，发布到<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://ohpm.openharmony.cn/">OHPM</a>私仓，供公司内部其他应用使用。<!-- -->
<!-- -->- 作为三方库，发布到<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://ohpm.openharmony.cn/">OHPM</a>中心仓，供其他应用使用。<!-- -->
<!-- -->- 多包（HAP/HSP）引用相同的HAR时，会造成多包间代码和资源的重复拷贝，从而导致应用包膨大。</div></td></tr><tr class="notion-simple-table-row notion-block-1594a55105cd4fc5b39f50c7c52ab161"><td class="" style="width:120px"><div class="notion-simple-table-cell">Shared Library</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/in-app-hsp-0000001774119898">HSP</a></div></td><td class="" style="width:800px"><div class="notion-simple-table-cell">动态共享包，运行时复用。<!-- -->
<!-- -->- 当前仅支持应用内共享。<!-- -->
<!-- -->- 当多包（HAP/HSP）同时引用同一个共享包时，采用HSP替代HAR，可以避免HAR造成的多包间代码和资源的重复拷贝，从而减小应用包大小。</div></td></tr></tbody></table><div class="notion-text notion-block-6b6494b466f34bb7a245d393ff413d8e">HAP、HSP、HAR支持的规格对比如下，其中“√”表示是，“×”表示否。</div><div class="notion-text notion-block-88e59c2f993442eb8447443f14f3aa59">开发者可以根据实际场景所需的能力，选择相应类型的包进行开发。在后续的章节中还会针对如何使用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hap-package-0000001820879541">HAP</a>、<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/har-package-0000001774279570">HAR</a>、<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/in-app-hsp-0000001774119898">HSP</a>分别展开详细介绍。</div><table class="notion-simple-table notion-block-93ae3d85f83e4e68addcb87986c195b9"><tbody><tr class="notion-simple-table-row notion-block-b184f40e98444564a1996ddc2934a1db"><td class="" style="width:675px"><div class="notion-simple-table-cell"><b>规格</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>HAP</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>HAR</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>HSP</b></div></td></tr><tr class="notion-simple-table-row notion-block-3c196c823bbd4f7ea2b804abb28c03d9"><td class="" style="width:675px"><div class="notion-simple-table-cell">支持在配置文件中声明<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/uiability-overview-0000001774119974">UIAbility</a>组件与<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/extensionability-overview-0000001774279654">ExtensionAbility</a>组件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">×</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">×</div></td></tr><tr class="notion-simple-table-row notion-block-03310ccc0f2247dc9fabdacf6ba8c2c5"><td class="" style="width:675px"><div class="notion-simple-table-cell">支持在配置文件中声明<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file-0000001820879553#ZH-CN_TOPIC_0000001820879553__pages%E6%A0%87%E7%AD%BE">pages</a>页面</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">×</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td></tr><tr class="notion-simple-table-row notion-block-18da57dc64be4fcbbdce8be016812c9a"><td class="" style="width:675px"><div class="notion-simple-table-cell">支持包含资源文件与.so文件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td></tr><tr class="notion-simple-table-row notion-block-6fef09b98efe4a38b754cd0d4de9d4b1"><td class="" style="width:675px"><div class="notion-simple-table-cell">支持依赖其他HAR文件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td></tr><tr class="notion-simple-table-row notion-block-8dd0a32775bb4f8e9fafac010b49500a"><td class="" style="width:675px"><div class="notion-simple-table-cell">支持依赖其他HSP文件</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">×</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td></tr><tr class="notion-simple-table-row notion-block-eb2a946b77bc4c06b9399c285b1f4215"><td class="" style="width:675px"><div class="notion-simple-table-cell">支持在设备上独立安装运行</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">√</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">×</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">×</div></td></tr></tbody></table><div class="notion-text notion-block-78b9e5bc2bba43198c47e003f39aa7a0"><b>说明</b></div><ul class="notion-list notion-list-disc notion-block-4a5e39cf51c04db69cafeecae87c08a9"><li>HAR虽然不支持在配置文件中声明pages页面，但是可以包含pages页面，并通过<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-routing-0000001820879797#ZH-CN_TOPIC_0000001820879797__%E5%91%BD%E5%90%8D%E8%B7%AF%E7%94%B1">命名路由</a>的方式进行跳转。</li></ul><ul class="notion-list notion-list-disc notion-block-9d823bb448824c7c9ba7712627a39369"><li>HAR和HSP均不支持循环依赖，也不支持依赖传递。</li></ul><div class="notion-blank notion-block-5c2ee06278df48a2a0ab727c27ff9b59"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[进阶：数据存储]]></title>
            <link>https://www.luechan.com/article/preferences</link>
            <guid>https://www.luechan.com/article/preferences</guid>
            <pubDate>Sun, 08 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Preferences，KV-Store和SQLite]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-6e6b89856a3a4831b6633e359f670568"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3e22835d338d4d26b36366560959d46c" data-id="3e22835d338d4d26b36366560959d46c"><span><div id="3e22835d338d4d26b36366560959d46c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3e22835d338d4d26b36366560959d46c" title="概述"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>概述</b></span></span></h2><div class="notion-text notion-block-16593cecae3e4fb8a916c6bba4b5eb2d">数据存储，即应用数据持久化，是指应用将内存中的数据通过文件或数据库的形式保存到设备上。内存中的数据形态通常是任意的数据结构或数据对象，存储介质上的数据形态可能是文本、数据库、二进制文件等。HarmonyOS标准系统支持典型的存储数据形态，包括用户首选项、键值型数据库、关系型数据库。</div><ul class="notion-list notion-list-disc notion-block-a1701304d16b4df3af1b4329db1d8193"><li><b>用户首选项（Preferences）</b>：通常用于保存应用的配置信息。数据通过文本的形式保存在设备中，应用使用过程中会将文本中的数据全量加载到内存中，所以访问速度快、效率高，但不适合需要存储大量数据的场景。</li></ul><ul class="notion-list notion-list-disc notion-block-645ec328717b4053a7c32118dd154905"><li><b>键值型数据库（KV-Store）</b>：一种非关系型数据库，其数据以“键值”对的形式进行组织、索引和存储，其中“键”作为唯一标识符。适合很少数据关系和业务关系的业务数据存储，同时因其在分布式场景中降低了解决数据库版本兼容问题的复杂度，和数据同步过程中冲突解决的复杂度而被广泛使用。相比于关系型数据库，更容易做到跨设备跨版本兼容。</li></ul><ul class="notion-list notion-list-disc notion-block-58497f86c0b34c75b1243d8da7b1949f"><li><b>关系型数据库（RelationalStore）</b>：一种关系型数据库，以行和列的形式存储数据，广泛用于应用中的关系型数据的处理，包括一系列的增、删、改、查等接口，开发者也可以运行自己定义的SQL语句来满足复杂业务场景的需要。</li></ul><div class="notion-blank notion-block-7d8a313dc3ac47309857c25fa7651ca0"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-d29a90312a15499b887b37d9d9ef7089" data-id="d29a90312a15499b887b37d9d9ef7089"><span><div id="d29a90312a15499b887b37d9d9ef7089" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d29a90312a15499b887b37d9d9ef7089" title="一、用户首选项"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>一、用户首选项</b></span></span></h2><div class="notion-text notion-block-785e9fac014a42a5bc85c85144318db7">用户首选项Preferences，类似于Android中的SharedPreferences，为应用提供Key-Value键值型的数据存储能力，常用于轻量级的数据存储，如应用配置。进程中每个文件对应一个Preferences实例，应用获取到实例后，可以从中读取数据，或者将数据存入实例中。通过调用flush方法可以将实例中的数据回写到文件里。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f800b2cd4bef403a9e377d55cf3f022f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:700px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240201110411.88730526807078185274438839600602:50001231000000:2800:3F1000B11EF7EEA587419AA79F619B7E95D896A4F7FF3CA4BCC2B07F74BBA08E.png?needInitFileName=true?needInitFileName=true&amp;t=f800b2cd-4bef-403a-9e37-7d55cf3f022f" alt="notion image" loading="lazy" decoding="async"/></div></figure><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3b3621937b064141a3f86d6a979ee576" data-id="3b3621937b064141a3f86d6a979ee576"><span><div id="3b3621937b064141a3f86d6a979ee576" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b3621937b064141a3f86d6a979ee576" title="1.1 首选项与非关系数据库的对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.1 首选项与非关系数据库的对比</span></span></h4><table class="notion-simple-table notion-block-921576539bad43e4856486708195abcc"><tbody><tr class="notion-simple-table-row notion-block-c271934418384564b46c0f99b76a0517"><td class="" style="width:409px"><div class="notion-simple-table-cell">分类</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">关系型数据库</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">用户首选项</div></td></tr><tr class="notion-simple-table-row notion-block-c8fa4a3f04064779bc97df8ed331e072"><td class="" style="width:409px"><div class="notion-simple-table-cell">数据库类型</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">关系型</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">非关系型，不保证遵循ACID（Atomicity, Consistency, Isolation and Durability）特性，数据之间无关系</div></td></tr><tr class="notion-simple-table-row notion-block-ba541f247abb48abbac49fe2c0e25c81"><td class="" style="width:409px"><div class="notion-simple-table-cell">使用场景</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">提供复杂场景下的本地数据库管理机制</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">对Key-Value结构的数据进行存取和持久化操作</div></td></tr><tr class="notion-simple-table-row notion-block-8b9abd166ce04967ba7c2b63027b8b4e"><td class="" style="width:409px"><div class="notion-simple-table-cell">存储方式</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">SQLite数据库</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">文件</div></td></tr><tr class="notion-simple-table-row notion-block-aaacf4a1494e4edeb36c94306bc7ae54"><td class="" style="width:409px"><div class="notion-simple-table-cell">约束与限制</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">1.连接池最大4个<!-- -->
<!-- -->2.同一时间只支持一个写操作</div></td><td class="" style="width:409px"><div class="notion-simple-table-cell">1.建议数据不超一万条<!-- -->
<!-- -->2.Key为string型</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-cfa407e79ebb489e840290c6dd152223" data-id="cfa407e79ebb489e840290c6dd152223"><span><div id="cfa407e79ebb489e840290c6dd152223" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cfa407e79ebb489e840290c6dd152223" title="1.2 接口说明"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>1.2 接口说明</b></span></span></h4><div class="notion-text notion-block-7494a1c9735e437fab3dcb60c5d91d55">以下是用户首选项持久化功能的相关接口，大部分为异步接口。异步接口均有callback和Promise两种返回形式，下表均以callback形式为例，更多接口及使用方式请见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/js-apis-data-preferences-0000001427745052-V2">用户首选项</a>。</div><table class="notion-simple-table notion-block-524331e0c97f41c1af651080ba27e151"><tbody><tr class="notion-simple-table-row notion-block-71d9d723bcab4f73abf7a9f769d71eb2"><td class="" style="width:613.5px"><div class="notion-simple-table-cell"><b>接口名称</b></div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell"><b>描述</b></div></td></tr><tr class="notion-simple-table-row notion-block-a185f233b22a4d09a8feb26c3d588187"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">getPreferences(context: Context, name: string, callback: AsyncCallback&lt;Preferences&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">获取Preferences实例。</div></td></tr><tr class="notion-simple-table-row notion-block-693731b8c6bb46ddb0a1e7faa1f208ae"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">put(key: string, value: ValueType, callback: AsyncCallback&lt;void&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">将数据写入Preferences实例，可通过flush将Preferences实例持久化。</div></td></tr><tr class="notion-simple-table-row notion-block-3baef853c9ff49469a454c4a1b6229e2"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">has(key: string, callback: AsyncCallback&lt;boolean&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">检查Preferences实例是否包含名为给定Key的存储键值对。给定的Key值不能为空。</div></td></tr><tr class="notion-simple-table-row notion-block-39c77ac38dae4799a34208b20ac67729"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">get(key: string, defValue: ValueType, callback: AsyncCallback&lt;ValueType&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">获取键对应的值，如果值为null或者非默认值类型，返回默认数据defValue。</div></td></tr><tr class="notion-simple-table-row notion-block-cc808d4e63c449c996782ee58396ef29"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">delete(key: string, callback: AsyncCallback&lt;void&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">从Preferences实例中删除名为给定Key的存储键值对。</div></td></tr><tr class="notion-simple-table-row notion-block-12aaef70f8c6476a92b871c4a1544417"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">flush(callback: AsyncCallback&lt;void&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">将当前Preferences实例的数据异步存储到用户首选项持久化文件中。</div></td></tr><tr class="notion-simple-table-row notion-block-ee54c9313adb445e85a8c9101036f4e9"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">on(type: &#x27;change&#x27;, callback: Callback&lt;{ key : string }&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">订阅数据变更，订阅的Key的值发生变更后，在执行flush方法后，触发callback回调。</div></td></tr><tr class="notion-simple-table-row notion-block-f7d73a46820d4975857a38d1f560c144"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">off(type: &#x27;change&#x27;, callback?: Callback&lt;{ key : string }&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">取消订阅数据变更。</div></td></tr><tr class="notion-simple-table-row notion-block-0bca19fe752a47998c6faa7b178845c4"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">deletePreferences(context: Context, name: string, callback: AsyncCallback&lt;void&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">从内存中移除指定的Preferences实例。若Preferences实例有对应的持久化文件，则同时删除其持久化文件。</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-dfd9565111d948fc94ff24f1c5dc1773" data-id="dfd9565111d948fc94ff24f1c5dc1773"><span><div id="dfd9565111d948fc94ff24f1c5dc1773" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dfd9565111d948fc94ff24f1c5dc1773" title="1.3 示例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3 示例</span></span></h4><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-727d95a6a4704893b394da5e03ba2fee" data-id="727d95a6a4704893b394da5e03ba2fee"><span><div id="727d95a6a4704893b394da5e03ba2fee" class="notion-header-anchor"></div><a class="notion-hash-link" href="#727d95a6a4704893b394da5e03ba2fee" title="二、键值型数据库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>二、键值型数据库</b></span></span></h2><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b83484041a7c40538e27598d355353e2" data-id="b83484041a7c40538e27598d355353e2"><span><div id="b83484041a7c40538e27598d355353e2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b83484041a7c40538e27598d355353e2" title="2.1 场景介绍"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2.1 场景介绍</b></span></span></h4><div class="notion-text notion-block-24e4a149dce946f39c38ab6aee94e444">键值型数据库存储键值对形式的数据，当需要存储的数据没有复杂的关系模型，比如存储商品名称及对应价格、员工工号及今日是否已出勤等，由于数据复杂度低，更容易兼容不同数据库版本和设备类型，因此推荐使用键值型数据库持久化此类数据。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-aa0e9ecfff614de3b5b0bfe5f2b39243" data-id="aa0e9ecfff614de3b5b0bfe5f2b39243"><span><div id="aa0e9ecfff614de3b5b0bfe5f2b39243" class="notion-header-anchor"></div><a class="notion-hash-link" href="#aa0e9ecfff614de3b5b0bfe5f2b39243" title="2.2 约束限制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2.2 约束限制</b></span></span></h4><ul class="notion-list notion-list-disc notion-block-c90c93beaaa74a6c842af077daf61847"><li>设备协同数据库，针对每条记录，Key的长度≤896 Byte，Value的长度&lt;4 MB。</li></ul><ul class="notion-list notion-list-disc notion-block-948a692570f5454d8d78fb9eb04ecaba"><li>单版本数据库，针对每条记录，Key的长度≤1 KB，Value的长度&lt;4 MB。</li></ul><ul class="notion-list notion-list-disc notion-block-d12e3bb698d14a4ca7b2ebd8d001b964"><li>每个应用程序最多支持同时打开16个键值型分布式数据库。</li></ul><ul class="notion-list notion-list-disc notion-block-2d69a70d11674d67922aba51b539dcc2"><li>键值型数据库事件回调方法中不允许进行阻塞操作，例如修改UI组件。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e8a0b3179308422a80ac084e2cae9bb5" data-id="e8a0b3179308422a80ac084e2cae9bb5"><span><div id="e8a0b3179308422a80ac084e2cae9bb5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e8a0b3179308422a80ac084e2cae9bb5" title="2.3 接口说明"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2.3 接口说明</b></span></span></h4><div class="notion-text notion-block-f9c16e8136e84adca7a284388d2e13e5">以下是键值型数据库持久化功能的相关接口，大部分为异步接口。异步接口均有callback和Promise两种返回形式，下表均以callback形式为例，更多接口及使用方式请见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/js-apis-distributedkvstore-0000001544703965-V2">分布式键值数据库</a>。</div><table class="notion-simple-table notion-block-ceb8bd1487464edb9d3452a895d67326"><tbody><tr class="notion-simple-table-row notion-block-59c379b2cafe45d59ae04ceb2a4f2370"><td class="" style="width:613.5px"><div class="notion-simple-table-cell"><b>接口名称</b></div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell"><b>描述</b></div></td></tr><tr class="notion-simple-table-row notion-block-9194ff8e7de14562988f4cd6e08c37c7"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">createKVManager(config: KVManagerConfig): KVManager</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">创建一个KVManager对象实例，用于管理数据库对象。</div></td></tr><tr class="notion-simple-table-row notion-block-49d26db6699b4245af27ccd3c76d5f43"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">getKVStore&lt;T&gt;(storeId: string, options: Options, callback: AsyncCallback&lt;T&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">指定Options和storeId，创建并得到指定类型的KVStore数据库。</div></td></tr><tr class="notion-simple-table-row notion-block-fc187777ce0b4edbb6e18455509c8f6f"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">put(key: string, value: Uint8Array|string|number|boolean, callback: AsyncCallback&lt;void&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">添加指定类型的键值对到数据库。</div></td></tr><tr class="notion-simple-table-row notion-block-731d3032348e48ee88d62975f3a4bbbd"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">get(key: string, callback: AsyncCallback&lt;Uint8Array|string|boolean|number&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">获取指定键的值。</div></td></tr><tr class="notion-simple-table-row notion-block-006ae798f0014702b9e636a8884aee00"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">delete(key: string, callback: AsyncCallback&lt;void&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">从数据库中删除指定键值的数据。</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-52041abc68844149801222184902f094" data-id="52041abc68844149801222184902f094"><span><div id="52041abc68844149801222184902f094" class="notion-header-anchor"></div><a class="notion-hash-link" href="#52041abc68844149801222184902f094" title="2.3 示例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.3 示例</span></span></h4><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-4a7da04c148a493dbd7def823b8aa9c7" data-id="4a7da04c148a493dbd7def823b8aa9c7"><span><div id="4a7da04c148a493dbd7def823b8aa9c7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4a7da04c148a493dbd7def823b8aa9c7" title="三、关系型数据库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>三、关系型数据库</b></span></span></h2><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-084a6eb9030b4dcc893b131e42a21212" data-id="084a6eb9030b4dcc893b131e42a21212"><span><div id="084a6eb9030b4dcc893b131e42a21212" class="notion-header-anchor"></div><a class="notion-hash-link" href="#084a6eb9030b4dcc893b131e42a21212" title="3.1 场景介绍"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3.1 场景介绍</b></span></span></h4><div class="notion-text notion-block-09c4b736c8c54c379751c09a22e840e6">关系型数据库基于SQLite组件，适用于存储包含复杂关系数据的场景，比如一个班级的学生信息，需要包括姓名、学号、各科成绩等，又或者公司的雇员信息，需要包括姓名、工号、职位等，由于数据之间有较强的对应关系，复杂程度比键值型数据更高，此时需要使用关系型数据库来持久化保存数据。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-76d4162f84454e6dbd75beb19f8fd085" data-id="76d4162f84454e6dbd75beb19f8fd085"><span><div id="76d4162f84454e6dbd75beb19f8fd085" class="notion-header-anchor"></div><a class="notion-hash-link" href="#76d4162f84454e6dbd75beb19f8fd085" title="3.2 基本概念"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3.2 基本概念</b></span></span></h4><ul class="notion-list notion-list-disc notion-block-4316dae28f8244518bfe8766481b4ec5"><li><b>谓词</b>：数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项，主要用来定义数据库的操作条件。</li></ul><ul class="notion-list notion-list-disc notion-block-5b2b5e9cef82438aa8da841ba5974efe"><li><b>结果集</b>：指用户查询之后的结果集合，可以对数据进行访问。结果集提供了灵活的数据访问方式，可以更方便地拿到用户想要的数据。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8d3228d584c945e7b9a5e9bee111365e" data-id="8d3228d584c945e7b9a5e9bee111365e"><span><div id="8d3228d584c945e7b9a5e9bee111365e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8d3228d584c945e7b9a5e9bee111365e" title="3.3 运作机制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3.3 运作机制</b></span></span></h4><div class="notion-text notion-block-fc5c4179012943fb8cbd8a65635faaed">关系型数据库对应用提供通用的操作接口，底层使用SQLite作为持久化存储引擎，支持SQLite具有的数据库特性，包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-10422842b97249e3911105715583763d" data-id="10422842b97249e3911105715583763d"><span><div id="10422842b97249e3911105715583763d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#10422842b97249e3911105715583763d" title="3.4 约束限制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3.4 约束限制</b></span></span></h4><ul class="notion-list notion-list-disc notion-block-148d18d79a3f4282aa426550ff6d3fe2"><li>系统默认日志方式是WAL（Write Ahead Log）模式，系统默认落盘方式是FULL模式。</li></ul><ul class="notion-list notion-list-disc notion-block-59790c7efe8040fa8fc657adbd153903"><li>数据库中连接池的最大数量是4个，用以管理用户的读操作。</li></ul><ul class="notion-list notion-list-disc notion-block-f79f6a0225bd489b99fb840aa367c8b4"><li>为保证数据的准确性，数据库同一时间只能支持一个写操作。</li></ul><ul class="notion-list notion-list-disc notion-block-ab82964511d04d4cbd6ee688b5185fe1"><li>当应用被卸载完成后，设备上的相关数据库文件及临时文件会被自动清除。</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1651188c551c4ec0b920143e06b7b5b8" data-id="1651188c551c4ec0b920143e06b7b5b8"><span><div id="1651188c551c4ec0b920143e06b7b5b8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1651188c551c4ec0b920143e06b7b5b8" title="3.5 接口说明"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3.5 接口说明</b></span></span></h4><div class="notion-text notion-block-9c677966f7464a3d87e7954fb46067c6">以下是关系型数据库持久化功能的相关接口，大部分为异步接口。异步接口均有callback和Promise两种返回形式，下表均以callback形式为例，更多接口及使用方式请见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/js-apis-data-relationalstore-0000001493744128-V2">关系型数据库</a>。</div><table class="notion-simple-table notion-block-bae76ca053e1429fb21f227a5e036684"><tbody><tr class="notion-simple-table-row notion-block-9d79e7fdb2e74c99bf2beb9a27977f9e"><td class="" style="width:613.5px"><div class="notion-simple-table-cell"><b>接口名称</b></div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell"><b>描述</b></div></td></tr><tr class="notion-simple-table-row notion-block-95dd7d62ed6e4ff1b0b6dbf914cb6c59"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">getRdbStore(context: Context, config: StoreConfig, callback: AsyncCallback&lt;RdbStore&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">获得一个相关的RdbStore，操作关系型数据库，用户可以根据自己的需求配置RdbStore的参数，然后通过RdbStore调用相关接口可以执行相关的数据操作。</div></td></tr><tr class="notion-simple-table-row notion-block-054e7f8379364144a6790f6cd843b946"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">executeSql(sql: string, bindArgs: Array&lt;ValueType&gt;, callback: AsyncCallback&lt;void&gt;):void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">执行包含指定参数但不返回值的SQL语句。</div></td></tr><tr class="notion-simple-table-row notion-block-1e93e490f4f048f8b48b0d6e077d95e2"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">insert(table: string, values: ValuesBucket, callback: AsyncCallback&lt;number&gt;):void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">向目标表中插入一行数据。</div></td></tr><tr class="notion-simple-table-row notion-block-9bd446fb2b704b238e73524313209a40"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">update(values: ValuesBucket, predicates: RdbPredicates, callback: AsyncCallback&lt;number&gt;):void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">根据RdbPredicates的指定实例对象更新数据库中的数据。</div></td></tr><tr class="notion-simple-table-row notion-block-eb1aa94ab4224d3ebafa4ac4fde0566a"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">delete(predicates: RdbPredicates, callback: AsyncCallback&lt;number&gt;):void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">根据RdbPredicates的指定实例对象从数据库中删除数据。</div></td></tr><tr class="notion-simple-table-row notion-block-d06e8ee80b194f05a151b001fc4e1aa9"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">query(predicates: RdbPredicates, columns: Array&lt;string&gt;, callback: AsyncCallback&lt;ResultSet&gt;):void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">根据指定条件查询数据库中的数据。</div></td></tr><tr class="notion-simple-table-row notion-block-868e68ded63c4e4392b492ccd8a745fe"><td class="" style="width:613.5px"><div class="notion-simple-table-cell">deleteRdbStore(context: Context, name: string, callback: AsyncCallback&lt;void&gt;): void</div></td><td class="" style="width:613.5px"><div class="notion-simple-table-cell">删除数据库。</div></td></tr></tbody></table><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-825d894eac75499a96028aba1e0f8af0" data-id="825d894eac75499a96028aba1e0f8af0"><span><div id="825d894eac75499a96028aba1e0f8af0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#825d894eac75499a96028aba1e0f8af0" title="3.6 示例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.6 示例</span></span></h4><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-5b3251df48504dbc8930a02d9edfe556" data-id="5b3251df48504dbc8930a02d9edfe556"><span><div id="5b3251df48504dbc8930a02d9edfe556" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5b3251df48504dbc8930a02d9edfe556" title="附：参考链接"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>附：参考链接</b></span></span></h2><ul class="notion-list notion-list-disc notion-block-b8f0012fab4b45c89e47464b864b23d3"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-data-preferences-0000001820880633">用户首选项参考</a></li></ul><ul class="notion-list notion-list-disc notion-block-22b6165e17934fa988b10416bf4d6935"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/app-data-persistence-overview-0000001505513497-V2">数据持久化概述</a></li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[核心应用组件系列：后台服务]]></title>
            <link>https://www.luechan.com/article/service</link>
            <guid>https://www.luechan.com/article/service</guid>
            <pubDate>Fri, 29 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[类似于Android四大组件中的Service]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-98c2203a116144e7b865aec860526eb1"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-9f30f3cd43c94d8796944fdd703bc367">OpenHarmony中，后台服务能力由<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-app-ability-serviceExtensionAbility.md">ServiceExtensionAbility</a>提供；<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-app-ability-serviceExtensionAbility.md">ServiceExtensionAbility</a>支持以启动和连接两种形式运行。</div><div class="notion-text notion-block-ead701403f66453d83d23969f762654e"><b>启动和连接后台服务的差别：</b></div><ul class="notion-list notion-list-disc notion-block-27580595849a45b3ac8170f0808696d8"><li>启动：AbilityA启动ServiceB，启动后AbilityA和ServiceB为弱关联，AbilityA退出后，ServiceB可以继续存在。</li></ul><ul class="notion-list notion-list-disc notion-block-3081940fe1cc4829b1431ec43b24ba91"><li>连接：AbilityA绑定ServiceB，绑定后AbilityA和ServiceB为强关联，AbilityA退出后，ServiceB也一起退出。</li></ul><div class="notion-text notion-block-fe0d958476ae498eb8a71cee246d3860"><b>系统应用和三方应用的差别：</b></div><ul class="notion-list notion-list-disc notion-block-865e3d12ad6c4aeba9f70e1c856f4a55"><li>系统应用可以调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability">startServiceExtensionAbility()</a>方法启动后台服务，也可以调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability">connectServiceExtensionAbility()</a>方法连接后台服务，</li></ul><ul class="notion-list notion-list-disc notion-block-ed5d91eed4a24a08860380edb24487b7"><li>三方应用只能调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability">connectServiceExtensionAbility()</a>方法连接后台服务。</li></ul><div class="notion-blank notion-block-e543bbf0afbc459d9d27d5d169549c72"> </div><div class="notion-text notion-block-2cd0cdc3741c410981582f4540c41681">本文描述中称被启动的ServiceExtensionAbility为服务端，称启动ServiceExtensionAbility的组件为客户端。本章节将从如下场景来介绍ServiceExtensionAbility的基本使用。</div><ul class="notion-list notion-list-disc notion-block-b94faa8240be4b3f916d385a19af8626"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-models/serviceextensionability.md#%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E5%90%8E%E5%8F%B0%E6%9C%8D%E5%8A%A1%E4%BB%85%E5%AF%B9%E7%B3%BB%E7%BB%9F%E5%BA%94%E7%94%A8%E5%BC%80%E6%94%BE">实现一个后台服务（Server，仅对系统应用开放）</a></li></ul><ul class="notion-list notion-list-disc notion-block-c12e483e371f4f5994175f4d9dfc7ba3"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-models/serviceextensionability.md#%E5%90%AF%E5%8A%A8%E4%B8%80%E4%B8%AA%E5%90%8E%E5%8F%B0%E6%9C%8D%E5%8A%A1%E4%BB%85%E5%AF%B9%E7%B3%BB%E7%BB%9F%E5%BA%94%E7%94%A8%E5%BC%80%E6%94%BE">启动一个后台服务（Client，仅对系统应用开放）</a></li></ul><ul class="notion-list notion-list-disc notion-block-b7f3dab7674a49b7be2adac77ced3002"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-models/serviceextensionability.md#%E8%BF%9E%E6%8E%A5%E4%B8%80%E4%B8%AA%E5%90%8E%E5%8F%B0%E6%9C%8D%E5%8A%A1">连接一个后台服务</a>（Client）</li></ul><blockquote class="notion-quote notion-block-34df7eb9a35442fa859eec12e5503106"><div>说明：</div><ol start="1" class="notion-list notion-list-numbered notion-block-2473513d26d247c288755ad25129b474"><li>OpenHarmony当前不支持三方应用实现ServiceExtensionAbility。如果三方开发者想要实现后台处理相关事务的功能，可以使用后台任务，具体请参见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/task-management/background-task-overview.md">后台任务</a>。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-c08b6da5c1304f6699693831b928345a"><li>三方应用的UIAbility组件可以通过Context连接系统提供的ServiceExtensionAbility。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-eb092ed2047b4a8da4baafa94de7f766"><li>三方应用需要在前台获焦的情况下才能连接系统提供的ServiceExtensionAbility。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-e3ee4b13483a42e4bcd719589c118b5a"><li>每个类型的ExtensionAbility都有自己的Context，ServiceExtensionAbility通过<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-serviceExtensionContext.md">ServiceExtensionContext</a>提供相关能力。</li></ol></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3316cd6735f6455e9c615812e6a8c0f0" data-id="3316cd6735f6455e9c615812e6a8c0f0"><span><div id="3316cd6735f6455e9c615812e6a8c0f0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3316cd6735f6455e9c615812e6a8c0f0" title="实现一个后台服务（Server，仅对系统应用开放）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>实现一个后台服务（Server，仅对系统应用开放）</b></span></span></h3><div class="notion-text notion-block-20a810ceafcd49818ad6afb868806462"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-app-ability-serviceExtensionAbility.md">ServiceExtensionAbility</a>提供了onCreate()、onRequest()、onConnect()、onDisconnect()和onDestory()生命周期回调，根据需要重写对应的回调方法。下图展示了ServiceExtensionAbility的生命周期。</div><div class="notion-blank notion-block-63cf0bc2e8a34eb495848ce5a3d90165"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-86610260b9ae4ef6ad41f89f816b0c9b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://gitee.com/openharmony/docs/raw/master/zh-cn/application-dev/application-models/figures/ServiceExtensionAbility-lifecycle.png?t=86610260-b9ae-4ef6-ad41-f89f816b0c9b" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c0d18624c7134bb49c462cabd3fcfa03"><b>图1 </b>ServiceExtensionAbility生命周期</div><div class="notion-blank notion-block-8b8cf54e10d44a1c9b752565e7698864"> </div><ul class="notion-list notion-list-disc notion-block-cd88fefbd8364d1b98f02a67a1d9e6fe"><li><b>onCreate</b> 服务被首次创建时触发该回调，开发者可以在此进行一些初始化的操作，例如注册公共事件监听等。</li><ul class="notion-list notion-list-disc notion-block-cd88fefbd8364d1b98f02a67a1d9e6fe"><blockquote class="notion-quote notion-block-ed27c7aa67e84406b368de26470baec3"><div>说明： 如果服务已创建，再次启动该ServiceExtensionAbility不会触发onCreate()回调。</div></blockquote></ul></ul><ul class="notion-list notion-list-disc notion-block-ee9a4762530b4a71a5d40590b00e0891"><li><b>onRequest</b> 当另一个组件调用startServiceExtensionAbility()方法启动该服务组件时，触发该回调。执行此方法后，服务会启动并在后台运行。</li></ul><ul class="notion-list notion-list-disc notion-block-bd718bbca90f45afb5fe635c829df775"><li><b>onConnect</b> 当另一个组件调用connectServiceExtensionAbility()方法与该服务连接时，触发该回调。开发者在此方法中，返回一个远端代理对象（IRemoteObject），客户端拿到这个对象后可以通过这个对象与服务端进行RPC通信。</li></ul><ul class="notion-list notion-list-disc notion-block-48c6ff7091cb4e71b4ced39e90146df2"><li><b>onDisconnect</b> 其他组件调用disconnectServiceExtensionAbility()方法时，如果没有任何其他组件连接该服务，触发该回调。</li></ul><ul class="notion-list notion-list-disc notion-block-7439d875f3a74f90a47b4a471c20bdca"><li><b>onDestroy</b> 当不再使用服务且准备将其销毁该实例时，触发该回调。开发者可以在该回调中清理资源，如注销监听等。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d045eaaf12e0488994c30a3dd2663d7f" data-id="d045eaaf12e0488994c30a3dd2663d7f"><span><div id="d045eaaf12e0488994c30a3dd2663d7f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d045eaaf12e0488994c30a3dd2663d7f" title="开发步骤"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>开发步骤</b></span></span></h3><div class="notion-text notion-block-ba4cdb8ba9d84cefbd35498e78825652">开发者在实现一个后台服务时，需要在DevEco Studio工程中手动新建一个ServiceExtensionAbility，具体步骤如下。</div><ol start="1" class="notion-list notion-list-numbered notion-block-9e0d43a27e7942a6bb4325b80434ed17"><li>在工程Module对应的ets目录下，右键选择“New &gt; Directory”，新建一个目录并命名为serviceextability。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-d808ad99b4834e17ab7e1a291090650a"><li>在serviceextability目录，右键选择“New &gt; TypeScript File”，新建一个TypeScript文件并命名为ServiceExtAbility.ts。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-20c9d2ee015643a1bd9aca4bae5f894f"><li>打开ServiceExtAbility.ts文件，导入<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-rpc.md">RPC通信模块</a>，重载onRemoteMessageRequest()方法，接收客户端传递过来的消息，并将处理的结果返回给客户端。REQUEST_VALUE用于校验客户端发送的服务请求码。</li><ol class="notion-list notion-list-numbered notion-block-20c9d2ee015643a1bd9aca4bae5f894f"></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-8455fa1b1e514b83b24f02df2d960110"><li>在ServiceExtAbility.ts文件中，增加导入ServiceExtensionAbility的依赖包，自定义类继承ServiceExtensionAbility并加上需要的生命周期回调。</li><ol class="notion-list notion-list-numbered notion-block-8455fa1b1e514b83b24f02df2d960110"></ol></ol><ol start="5" class="notion-list notion-list-numbered notion-block-5d356c82e9f341848fa3fa5f1b179ae2"><li>在工程Module对应的<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/module-configuration-file.md">module.json5配置文件</a>中注册ServiceExtensionAbility，type标签需要设置为“service”，srcEntrance标签表示当前ExtensionAbility组件所对应的代码路径。</li><ol class="notion-list notion-list-numbered notion-block-5d356c82e9f341848fa3fa5f1b179ae2"></ol></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-337a8804c7fe4a098a281d1f2b12dc9c" data-id="337a8804c7fe4a098a281d1f2b12dc9c"><span><div id="337a8804c7fe4a098a281d1f2b12dc9c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#337a8804c7fe4a098a281d1f2b12dc9c" title="启动一个后台服务（Client，仅对系统应用开放）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>启动一个后台服务（Client，仅对系统应用开放）</b></span></span></h3><div class="notion-text notion-block-e7bfc3e4c57a47eca789dce3a20da401">系统应用通过<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability">startServiceExtensionAbility()</a>方法启动一个后台服务，服务的<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonrequest">onRequest()</a>回调就会被调用，并在该回调方法中接收到调用者传递过来的want对象。后台服务启动后，其生命周期独立于客户端，即使客户端已经销毁，该后台服务仍可继续运行。因此，后台服务需要在其工作完成时通过调用ServiceExtensionContext的<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself">terminateSelf()</a>来自行停止，或者由另一个组件调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability">stopServiceExtensionAbility()</a>来将其停止。</div><blockquote class="notion-quote notion-block-f2ff3827e7e54109a284aedaea2efa2f"><div>说明： ServiceExtensionContext的startServiceExtensionAbility()、stopServiceExtensionAbility()和terminateSelf()为系统接口，三方应用不支持调用。</div></blockquote><ol start="1" class="notion-list notion-list-numbered notion-block-1f2897f99d76402e8171e9bda642082e"><li>在系统应用中启动一个新的ServiceExtensionAbility。示例中的context的获取方式请参见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-models/uiability-usage.md#%E8%8E%B7%E5%8F%96uiability%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E4%BF%A1%E6%81%AF">获取UIAbility的上下文信息</a>。</li><ol class="notion-list notion-list-numbered notion-block-1f2897f99d76402e8171e9bda642082e"></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-733a10b2965a40439a6a46fb5d1f9412"><li>在系统应用中停止一个已启动的ServiceExtensionAbility。</li><ol class="notion-list notion-list-numbered notion-block-733a10b2965a40439a6a46fb5d1f9412"></ol></ol><ol start="3" class="notion-list notion-list-numbered notion-block-7e3d61d7bd1443d0841ff550a1a0b6ea"><li>已启动的ServiceExtensionAbility停止自身。</li><ol class="notion-list notion-list-numbered notion-block-7e3d61d7bd1443d0841ff550a1a0b6ea"></ol></ol><blockquote class="notion-quote notion-block-5b411401275642ea8641785c3119ccc2"><div>说明： 后台服务可以在后台长期运行，为了避免资源浪费，需要对后台服务的生命周期进行管理。即一个后台服务完成了请求方的任务，需要及时销毁。销毁已启动的后台服务有两种方式：</div><ul class="notion-list notion-list-disc notion-block-6db97dd5592c46cebbbbaf9c166010ac"><li>后台服务自身调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself">terminateSelf()</a>方法来自行停止。</li></ul><ul class="notion-list notion-list-disc notion-block-ec77cb1d8d39458bb9421f755594a981"><li>由其他组件调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability">stopServiceExtensionAbility()</a>方法来停止。</li></ul><div class="notion-text notion-block-0690db10334c4bc0957a715cd019a3ed">调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself">terminateSelf()</a>或<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability">stopServiceExtensionAbility()</a>方法之后，系统将销毁后台服务。</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3ad7bb629fe64dc9b97c1dc444a2a74a" data-id="3ad7bb629fe64dc9b97c1dc444a2a74a"><span><div id="3ad7bb629fe64dc9b97c1dc444a2a74a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3ad7bb629fe64dc9b97c1dc444a2a74a" title="连接一个后台服务（Client）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>连接一个后台服务（Client）</b></span></span></h3><div class="notion-text notion-block-68a5c6041ad04e79bbcbcd253de19ba6">系统应用或者三方应用可以通过<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability">connectServiceExtensionAbility()</a>连接一个服务（在Want对象中指定启动的目标服务），服务的<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonconnect">onConnect()</a>就会被调用，并在该回调方法中接收到调用者传递过来的Want对象，从而建立长连接。</div><div class="notion-text notion-block-5bfba36202764bb8883cc29f66da0c30">ServiceExtensionAbility服务组件在<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonconnect">onConnect()</a>中返回IRemoteObject对象，开发者通过该IRemoteObject定义通信接口，用于客户端与服务端进行RPC交互。多个客户端可以同时连接到同一个后台服务，客户端完成与服务的交互后，客户端需要通过调用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability">disconnectServiceExtensionAbility()</a>来断开连接。如果所有连接到某个后台服务的客户端均已断开连接，则系统会销毁该服务。</div><ul class="notion-list notion-list-disc notion-block-922029c78d5c4933b41d4add92b3ac79"><li>使用connectServiceExtensionAbility()建立与后台服务的连接。示例中的context的获取方式请参见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-models/uiability-usage.md#%E8%8E%B7%E5%8F%96uiability%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E4%BF%A1%E6%81%AF">获取UIAbility的上下文信息</a>。</li><ul class="notion-list notion-list-disc notion-block-922029c78d5c4933b41d4add92b3ac79"></ul></ul><ul class="notion-list notion-list-disc notion-block-52b34867f79a43d7943f318c479c55a7"><li>使用disconnectServiceExtensionAbility()断开与后台服务的连接。</li><ul class="notion-list notion-list-disc notion-block-52b34867f79a43d7943f318c479c55a7"></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-bb6aa6fe7ddf40f8a824ff59d7c92eca" data-id="bb6aa6fe7ddf40f8a824ff59d7c92eca"><span><div id="bb6aa6fe7ddf40f8a824ff59d7c92eca" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bb6aa6fe7ddf40f8a824ff59d7c92eca" title="相关示例"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>相关示例</b></span></span></h3><div class="notion-text notion-block-eba7f6e85f07456e91b6aeea4fe83c39">针对ServiceExtensionAbility开发，有以下相关示例可供参考：</div><ul class="notion-list notion-list-disc notion-block-717ce93ee2984448846a156ac4ab9112"><li><code class="notion-inline-code"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/applications_app_samples/tree/master/ability/AbilityConnectServiceExtension">AbilityConnectServiceExtension</a></code><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/applications_app_samples/tree/master/ability/AbilityConnectServiceExtension">：Ability与ServiceExtensionAbility通信（ArkTS）（API9）（Full SDK）</a></li></ul><ul class="notion-list notion-list-disc notion-block-7558494561b64bfcbef03ef660ff7c51"><li><code class="notion-inline-code"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/applications_app_samples/tree/master/ability/ServiceExtAbility">ServiceExtAbility</a></code><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://gitee.com/openharmony/applications_app_samples/tree/master/ability/ServiceExtAbility">：StageExtAbility的创建与使用（ArkTS）（API9）（Full SDK）</a></li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[核心应用组件系列：数据共享]]></title>
            <link>https://www.luechan.com/article/data-share</link>
            <guid>https://www.luechan.com/article/data-share</guid>
            <pubDate>Sun, 20 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[类似于Android四大组件中的ContentProvider]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-7f2bada392c040b1808aca68b5f3bf1c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-d5010d9892dd4f18a847a7bfec4c5a9b">跨应用访问数据时，可以通过DataShareExtensionAbility拉起数据提供方的应用以实现对数据的访问。</div><div class="notion-text notion-block-218d0fc69a5249fbb56c31f1646939b4">此种方式支持跨应用拉起数据提供方的DataShareExtension，数据提供方的开发者可以在回调中实现灵活的业务逻辑。用于跨应用复杂业务场景。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-002466f3449a412db8d13f6556edc82a" data-id="002466f3449a412db8d13f6556edc82a"><span><div id="002466f3449a412db8d13f6556edc82a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#002466f3449a412db8d13f6556edc82a" title="运作机制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>运作机制</b></span></span></h2><div class="notion-text notion-block-fbe5ac4b5e664af787cf104258250362">数据共享可分为数据的提供方和访问方两部分。</div><ul class="notion-list notion-list-disc notion-block-0bc9d302522d419cb49092ab1800958d"><li>数据提供方：<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V1/js-apis-application-datashareextensionability-0000001630306001-V1">DataShareExtensionAbility</a>，可以选择性实现数据的增、删、改、查，以及文件打开等功能，并对外共享这些数据。</li></ul><ul class="notion-list notion-list-disc notion-block-848a628e741e44929c9f4cf68f0cb93b"><li>数据访问方：由<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V1/js-apis-data-datashare-0000001580185594-V1#ZH-CN_TOPIC_0000001714587629__datasharecreatedatasharehelper">createDataShareHelper()</a>方法所创建的工具类，利用工具类，便可以访问提供方提供的这些数据。</li></ul><div class="notion-text notion-block-41fb2136f56445f497de4924d7843256"><b>图1</b> 数据共享运作机制</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-aa73d8db293741ce89307e222330e291"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:700px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240415145258.08121627175266405204360129646672:50001231000000:2800:40975E279906A7A5CFF1C71541B582AA5C5F593C266DB4057362C197D920A8E2.jpg?needInitFileName=true?needInitFileName=true&amp;t=aa73d8db-2937-41ce-8930-7e222330e291" alt="notion image" loading="lazy" decoding="async"/></div></figure><ul class="notion-list notion-list-disc notion-block-58f001cf68144ffd8772665a6451f0a9"><li>DataShareExtensionAbility模块为数据提供方，实现跨应用数据共享的相关业务。</li></ul><ul class="notion-list notion-list-disc notion-block-ba2e85760d694d8190520d0bc905955b"><li>DataShareHelper模块为数据访问方，提供各种访问数据的接口，包括增删改查等。</li></ul><ul class="notion-list notion-list-disc notion-block-d6d32e87f4e343769ced1b7278da12f9"><li>数据访问方与提供方通过IPC进行通信，数据提供方可以通过数据库实现，也可以通过其他数据存储方式实现。</li></ul><ul class="notion-list notion-list-disc notion-block-d1899df93af742da966160a1515946b7"><li>ResultSet模块通过共享内存实现，用于存储查询数据得到的结果集，并提供了遍历结果集的方法。</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-2faa75539c994871b2987d7e7ed69c82" data-id="2faa75539c994871b2987d7e7ed69c82"><span><div id="2faa75539c994871b2987d7e7ed69c82" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2faa75539c994871b2987d7e7ed69c82" title="实现说明"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>实现说明</b></span></span></h2><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-46792f4c455b4b678429c80874d0e380" data-id="46792f4c455b4b678429c80874d0e380"><span><div id="46792f4c455b4b678429c80874d0e380" class="notion-header-anchor"></div><a class="notion-hash-link" href="#46792f4c455b4b678429c80874d0e380" title="数据提供方应用的开发（仅限系统应用）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>数据提供方应用的开发（仅限系统应用）</b></span></span></h4><div class="notion-text notion-block-aec6f8e54977496eba9d676c931b22b8"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V1/js-apis-application-datashareextensionability-0000001630306001-V1">DataShareExtensionAbility</a>提供以下API，根据需要重写对应回调方法。</div><ul class="notion-list notion-list-disc notion-block-3c8034b6deeb40eaaa9c08428f49f111"><li><b>onCreate</b>：DataShare客户端连接DataShareExtensionAbility服务端时，服务端需要在此回调中实现初始化业务逻辑，该方法可以选择性重写。</li></ul><ul class="notion-list notion-list-disc notion-block-a997c08989a14c2998f39c3d88302cb8"><li><b>insert</b>：业务函数，客户端请求插入数据时回调此接口，服务端需要在此回调中实现插入数据功能，该方法可以选择性重写。</li></ul><ul class="notion-list notion-list-disc notion-block-e0f0aaef97914e44bc6701f0f5227be5"><li><b>update</b>：业务函数，客户端请求更新数据时回调此接口，服务端需要在此回调中实现更新数据功能，该方法可以选择性重写。</li></ul><ul class="notion-list notion-list-disc notion-block-6270900878904bc8834268e103c78cab"><li><b>delete</b>：业务函数，客户端请求删除数据时回调此接口，服务端需要在此回调中实现删除数据功能，该方法可以选择性重写。</li></ul><ul class="notion-list notion-list-disc notion-block-8e4ce25edb424a488ccfa5839060ab0c"><li><b>query</b>：业务函数，客户端请求查询数据时回调此接口，服务端需要在此回调中实现查询数据功能，该方法可以选择性重写。</li></ul><ul class="notion-list notion-list-disc notion-block-d2588460501c4459af4716d2651bf945"><li><b>batchInsert</b>：业务函数，客户端请求批量插入数据时回调此接口，服务端需要在此回调中实现批量插入数据的功能，该方法可以选择性重写。</li></ul><ul class="notion-list notion-list-disc notion-block-e954e90a016640dda239b5055420f6c9"><li><b>normalizeUri</b>：业务函数，客户端给定的URI转换为服务端使用的URI时回调此接口，该方法可以选择性重写。</li></ul><ul class="notion-list notion-list-disc notion-block-ac767b5ad56f4f9994c8c6a3bb87200a"><li><b>denormalizeUri</b>：业务函数，服务端使用的URI转换为客户端传入的初始URI时服务端回调此接口，该方法可以选择性重写。</li></ul><div class="notion-text notion-block-e88975458e0b49ae9f13bf4ec2b334d1">开发者在实现一个数据共享服务时，需要在DevEco Studio工程中手动新建一个DataShareExtensionAbility，具体步骤如下。</div><ol start="1" class="notion-list notion-list-numbered notion-block-e220763c9a0845c990604ae0d12d7058"><li>在工程Module对应的ets目录下，右键选择“New &gt; Directory”，新建一个目录并命名为DataShareExtAbility。</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-98c9b17b758b417e8c7b77b7b924b1f4"><li>在DataShareAbility目录，右键选择“New &gt; TypeScript File”，新建一个TypeScript文件并命名为DataShareExtAbility.ts。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-779bb24146e840488bb51de01b569fa9"><li>在DataShareExtAbility.ts文件中，导入</li><ol class="notion-list notion-list-numbered notion-block-779bb24146e840488bb51de01b569fa9"><div class="notion-text notion-block-b5f0c57d955e4327ac9e2a62d709227c">@ohos.application.DataShareExtensionAbility模块，开发者可根据应用需求选择性重写其业务实现。例如数据提供方只提供插入、删除和查询服务，则可只重写这些接口，并导入对应的基础依赖模块。</div></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-4c925a7c1306416da9785d079d3827ab"><li>数据提供方的业务实现由开发者自定义。例如可以通过数据库、读写文件或访问网络等各方式实现数据提供方的数据存储。</li><ol class="notion-list notion-list-numbered notion-block-4c925a7c1306416da9785d079d3827ab"></ol></ol><ol start="5" class="notion-list notion-list-numbered notion-block-f077f41c7cf14168aa7757fdbc8f93e7"><li>在module.json5中定义DataShareExtensionAbility。</li><ol class="notion-list notion-list-numbered notion-block-f077f41c7cf14168aa7757fdbc8f93e7"><div class="notion-text notion-block-1a7a5d8f51904b2faf8af686d129c2b1"><b>表1</b> module.json5对应属性字段</div><table class="notion-simple-table notion-block-44f159bc8a1c4bb184ae9bb4015752ad"><tbody><tr class="notion-simple-table-row notion-block-7ff55b8985d047b981c8322af9f0d2d1"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>属性名称</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>备注说明</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>必填</b></div></td></tr><tr class="notion-simple-table-row notion-block-677e5fee48b0460dae238762069f727b"><td class="" style="width:120px"><div class="notion-simple-table-cell">name</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Ability名称，对应Ability派生的ExtensionAbility类名。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td></tr><tr class="notion-simple-table-row notion-block-2cf0546e316f4e11b3f2b8e3de24c13c"><td class="" style="width:120px"><div class="notion-simple-table-cell">type</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">Ability类型，DataShare对应的Ability类型为“dataShare”，表示基于datashare模板开发的。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td></tr><tr class="notion-simple-table-row notion-block-e28bdd2226f647ad8a2db3d58b5e03bb"><td class="" style="width:120px"><div class="notion-simple-table-cell">uri</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">通信使用的URI，是客户端链接服务端的唯一标识。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td></tr><tr class="notion-simple-table-row notion-block-d1a3611b60dc42888761539599e879c3"><td class="" style="width:120px"><div class="notion-simple-table-cell">exported</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">对其他应用是否可见，设置为true时，才能与其他应用进行通信传输数据。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td></tr><tr class="notion-simple-table-row notion-block-d05ea8dcb24744fd95308f945303b0f4"><td class="" style="width:120px"><div class="notion-simple-table-cell">readPermission</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">访问数据时需要的权限，不配置默认不进行读权限校验。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">否</div></td></tr><tr class="notion-simple-table-row notion-block-2d35aefb8c0e4b7db646a348f83f9ccd"><td class="" style="width:120px"><div class="notion-simple-table-cell">writePermission</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">修改数据时需要的权限，不配置默认不进行写权限校验。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">否</div></td></tr><tr class="notion-simple-table-row notion-block-5a04e42724954da18e91007833c6fda1"><td class="" style="width:120px"><div class="notion-simple-table-cell">metadata</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">增加静默访问所需的额外配置项，包含name和resource字段。
name类型固定为&quot;ohos.extension.dataShare&quot;，是配置的唯一标识。
resource类型固定为&quot;$profile:data_share_config&quot;，表示配置文件的名称为data_share_config.json。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">若Ability启动模式为&quot;singleton&quot;，则metadata必填，Ability启动模式可见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V1/module-structure-0000001580025738-V1#ZH-CN_TOPIC_0000001714627309__abilities%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84">abilities对象的内部结构-launchType</a>；其他情况下无需填写。</div></td></tr></tbody></table><div class="notion-text notion-block-3d3a90ed6c6a4a98a584e9a214d5cd1f"><b>module.json5配置样例：</b></div><div class="notion-text notion-block-54ca2a013ef14e9391abb961ad69d4c6"><b>表2</b> data_share_config.json对应属性字段</div><table class="notion-simple-table notion-block-a8218cefd625485790d98f5b4866e938"><tbody><tr class="notion-simple-table-row notion-block-1e482910fcc64da4b83ee695369d10a1"><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>属性名称</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>备注说明</b></div></td><td class="" style="width:120px"><div class="notion-simple-table-cell"><b>必填</b></div></td></tr><tr class="notion-simple-table-row notion-block-eb87ce52c7a34a9a97bc992bb499fb42"><td class="" style="width:120px"><div class="notion-simple-table-cell">tableConfig</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">配置标签。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td></tr><tr class="notion-simple-table-row notion-block-c3f72c789614421a915cb1761f1552eb"><td class="" style="width:120px"><div class="notion-simple-table-cell">uri</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">指定配置生效的范围，uri支持以下三种格式，优先级为表配置&gt;库配置&gt;*，如果同时配置，高优先级会覆盖低优先级 。
1. &quot;*&quot; : 所有的数据库和表。
2. &quot;datashare:///{bundleName}/{moduleName}/{storeName}&quot; : 指定数据库。
3. &quot;datashare:///{bundleName}/{moduleName}/{storeName}/{tableName}&quot; : 指定表。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td></tr><tr class="notion-simple-table-row notion-block-108a811b52b9400b97d15663c78dad3f"><td class="" style="width:120px"><div class="notion-simple-table-cell">crossUserMode</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">标识数据是否为多用户共享，配置为1则多用户数据共享，配置为2则多用户数据隔离。</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">是</div></td></tr></tbody></table><div class="notion-text notion-block-85d4bf5bbcb54596979e2f3378ff4bf9"><b>data_share_config.json配置样例</b></div></ol></ol><div class="notion-text notion-block-27a40952eaec4954bcf5963893a41f1f"><b>数据访问方应用的开发</b>
1. 导入基础依赖包。</div><div class="notion-text notion-block-c0c2692b31454521a2823492e85780ef">2. 定义与数据提供方通信的URI字符串。</div><div class="notion-text notion-block-f38b6e9a47b0440aab22c63c9f7a6c41">3. 创建工具接口类对象。</div><div class="notion-text notion-block-651d32a374bd4f80a139ba313ef90055">4. 获取到接口类对象后，便可利用其提供的接口访问提供方提供的服务，如进行数据的增删改查等。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[核心应用组件系列：公共事件  ~ ]]></title>
            <link>https://www.luechan.com/article/ces</link>
            <guid>https://www.luechan.com/article/ces</guid>
            <pubDate>Wed, 16 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[类似于Android四大组件中的BroadcastReceiver]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-204fe69da0284c40ac6a45c4cd2a32e9"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-4b8138ce4c234afcb3e7f5ef18781f42">CES（Common Event Service，公共事件服务）为应用程序提供订阅、发布、退订公共事件的能力。</div><div class="notion-text notion-block-d044e1755d8b41a09e00a94ca27d247d">公共事件从系统角度可分为：系统公共事件和自定义公共事件。</div><ul class="notion-list notion-list-disc notion-block-670d578021b8408db7f888c3aca458a6"><li>系统公共事件：CES内部定义的公共事件，当前仅支持系统应用和系统服务发布，例如HAP安装，更新，卸载等公共事件。目前支持的系统公共事件请参见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references/commoneventmanager-definitions-0000001813576516">系统公共事件列表</a>。</li></ul><ul class="notion-list notion-list-disc notion-block-649bad10a60046108d860f3af38a3fec"><li>自定义公共事件：应用定义的公共事件，可用于实现跨进程的事件通信能力。</li></ul><div class="notion-text notion-block-6af3e7b42a9e493fb2c56adf8924d288">公共事件按发送方式可分为：无序公共事件、有序公共事件和粘性公共事件。</div><ul class="notion-list notion-list-disc notion-block-09f1016bf12248cd8aaded62864269df"><li>无序公共事件：CES在转发公共事件时，不考虑订阅者是否接收到该事件，也不保证订阅者接收到该事件的顺序与其订阅顺序一致。</li></ul><ul class="notion-list notion-list-disc notion-block-ec63dcffab57437ab5a902d2a0cf5c80"><li>有序公共事件：CES在转发公共事件时，根据订阅者设置的优先级等级，优先将公共事件发送给优先级较高的订阅者，等待其成功接收该公共事件之后再将事件发送给优先级较低的订阅者。如果有多个订阅者具有相同的优先级，则他们将随机接收到公共事件。</li></ul><ul class="notion-list notion-list-disc notion-block-fcd6fca311bb49e8b700f60981010874"><li>粘性公共事件：能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到，而粘性公共事件的特殊性就是可以先发送后订阅，同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务，粘性事件发送后会一直存在系统中，且发送者需要申请ohos.permission.COMMONEVENT_STICKY权限，配置方式请参见<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/declare-permissions-0000001820999665">声明权限</a>。</li></ul><div class="notion-text notion-block-1e951e09ddc1413ca13d18f0bc87c53d">每个应用都可以按需订阅公共事件，订阅成功，当公共事件发布时，系统会将其发送给对应的应用。这些公共事件可能来自系统、其他应用和应用自身。</div><div class="notion-text notion-block-4a090a5a696d40809fd9257b8a93b521"><b>图1</b> 公共事件示意图</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-54c2b1e04feb4ceeac8a649ab49ae867"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:700px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://alliance-communityfile-drcn.dbankcdn.com/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20240612140910.86748694032146133300101139949044:50001231000000:2800:85D992E06E701F871F63120E6F383587A43ABB67F98AB7F7B7FC31198FFC1A91.png?needInitFileName=true?needInitFileName=true&amp;t=54c2b1e0-4feb-4cee-ac8a-649ab49ae867" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-de70b63f581d46c08b574cbd771f0f80"> </div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>