文档管理中心
我的
推荐
最热
最新
其他
已解决
未解决
还要下载卓易通   太麻烦了   

评论2

浏览 7

发布于32分钟前
App内嵌H5页面,H5通过JSBridge调用Native 能力(读取本地文件列表、批量处理数据、生成缩略图)。注册方式:webviewController.registerJavaScriptProxy({ ... }, 'nativeBridge', ...);现象:H5 触发一个"读取并解析 5000 条本地记录"的桥接方法后,整个页面卡死 1-2 秒,滑动和点击全无响应桥接方法返回较大对象给 H5,偶发报"对象无法跨线程序列化"或数据错乱

评论3

浏览 11

发布于39分钟前
元服务被 App 通过 startAbility 拉起并带一个 taskId 过去。APP侧代码大概这样:const want: Want = { bundleName: 'com.example.myservice', abilityName: 'EntryAbility', parameters: { scene: 'share', taskId: '8848' } } context.startAbility(want)元服务 EntryAbility 里 onCreate(want) 里读 want.parameters,第一次能拿到。但同一个元服务已经在后台跑着、APP再点一次唤起时,taskId 就变成 undefined 了,偶尔甚至连第一次都是空的。文档翻遍了也没说清这参数是哪丢的

评论1

浏览 10

发布于41分钟前
Mate 80 Pro Max机型(设备型号代码:SGT-AL10),请问什么时候可以申请加入本轮招募白名单及开放呢?

评论295

浏览 14.7k

发布于2026-06-21 10:44
哪些机型可以升级到鸿蒙OS7?

评论1

浏览 15

发布于52分钟前
用了Mate90的,感觉咋样?准备入手

评论2

浏览 24

发布于2小时前
正在开发的一个银行App首页同时有广告轮播、资产总览、消息红点、风控探针和离线缓存恢复,直接在aboutToCreate全量构建会让首帧超过预算,怎样按视口拆成关键路由、次关键卡片和异步数据三层,保证用户点转账入口时不需要等非必要模块测量完成?

评论5

浏览 33

发布于4小时前
Nova12、13、14Mate60、70这个月有希望吗 都好久了 不会等到10月吧

评论108

浏览 4.9k

发布于2026-08-12 23:09
想开发一个专业录像App实现类似iOS和Android上类似blackmagic cam的功能,能够让用户直接内置一些LUT作为预设滤镜,也可以让用户自由导入LUT,但是目前H-Log没有白皮书,无法制作匹配的LUT,也无法比较准确的实现示波器和直方图以及伪彩色等专业功能。具体的白皮书内容可以参考阿莱的白皮书:https://www.arri.com/resource/blob/278790/f3318e8c9c65617d8c5ca3f8b3e32051/2023-05-arri-logc4-specification-data.pdf

评论2

浏览 21

发布于4小时前
用RichText组件加载富文本,怎样拦截标签的点击事件并在应用内打开链接而不是拉起浏览器?这个拉起浏览器就很烦人

评论5

浏览 24

发布于4小时前
1.华为系统是否支持Android原生app拉起系统实况窗?2.如果华为系统支持原生app拉起实况窗功能,是否需要集成华为官方Push能力才能使用实况窗?

评论4

浏览 25

发布于5小时前
使用地图时,在转换底部导航栏为6.1+沉浸式导航栏时,发现地图显示的左下角LOGO及右下角放大缩小按钮的位置,无法自定义, 导致被导航栏遮盖。这个要如何解决?

评论2

浏览 18

发布于5小时前
2026年9月22日设备管理中已经有100台设备了,准备新增一台设备,需要先移除一台历史的设备9D442D121xxxxxxxxxxxxxxxxxx53,但是删除后提示 部分设备已被HarmonyAppProvision使用,无法删除。 按照官方文档已经操作了 勾选待删掉的设备,将设备与Profile解绑。确定设备注册时间是2025-05-14 17:33:08 但是仍然没有成功,已确定只有这一个profile在使用

评论2

浏览 8

发布于5小时前
请问日和在一个text组件内实现以下效果在一段正常文本末尾跟上一个有背景色与圆角的字号小于其他文本布局,文本行数与内容长度不定

评论6

浏览 39

发布于5小时前
设备/环境:SGT-AL10 · HarmonyOS 7.0.0.105 · API 26 · DevEco Studio(hms SDK,UIDesignKit 声明 6.1.0(23)/6.1.1(24));应用 metadata 已配置 ohos.arkui.UIMaterial.state = "enable";targetAPIVersion ≥ 26;entry 模块;系统设置"沉浸光感" = 强(最高档)。问题现象:底部导航(悬浮胶囊 + 独立圆形)由普通 ArkUI 组件(Stack/Row)通过 systemMaterial(new uiMaterial.ImmersiveMaterial(...)) 接入沉浸式系统材质。HarmonyOS 7.0.0.105 SP6 系统更新之前:胶囊呈现真实玻璃质感(折射/光晕/通透)。SP6 更新之后:同一代码、同一设备、未改任何配置——胶囊变成纯透明的卡片(背后内容直接透出,无任何材质滤镜/折射/高光;看起来就像完全没有材质)。已按官方文档验证:按"沉浸光感"官方指南示例 1 的写法复刻(Column/Stack + .backgroundColor(Color.Transparent) 写在 .systemMaterial(...) 之前 + borderRadius + 顺序正确),同样失效。按"通用组件封装"实践(ImmersiveSurface:独立组件 + BuilderParam 内容 + 透明背景 + borderRadius + clip(true) + systemMaterial 最后),同样失效。运行时探针证据(关键):deviceInfo.apiAvailable('26.0.0') = true;uiMaterial.getMaterialInfo().state = 1(≠ DISABLE)→ 应用侧门全过;new uiMaterial.ImmersiveMaterial({ style: REGULAR, materialColor: '#80FF0000', interactive: true, lightEffect: {color: undefined} }) 传入 systemMaterial 后,50% 红色 materialColor 在画面上零差异(胶囊未变粉)——证明材质滤镜完全未被渲染(不是"样式选错/背景遮挡"类问题)。对照:同一设备上,系统组件的表面(如音乐条、系统设置预览)沉浸光感正常;HDS HdsTabs 官方悬浮页签(barFloatingStyle.systemMaterialEffect,materialType/materialLevel 模式)玻璃材质正常——唯独第三方应用里自定义 ArkUI 节点的 systemMaterial 不渲染。求助点:自定义 ArkUI 组件(Stack/Row/Column 等普通容器)的 systemMaterial 在 7.0.0.105(SP6) 是否被限制/降级?是否已有已知问题或需要新的启用条件?应用侧如何判定设备的沉浸光感算力档位(低/中/高)与全局材质等级?官方指南示例 5 提到 uiMaterial.getGlobalMaterialLevel() / uiMaterial.isImmersiveMaterialSupported(),但当前 SDK 的 ArkTS 声明中不存在这两个 API(能力清单 ArkUI.json 中有声明,since 26.0.0)——这是声明回退还是需要更高 SDK 补丁?如果自定义组件的材质确实无法恢复,官方推荐的自定义底部导航正确载体是什么(HDS 已确认可用,但存在自定义页签内容/动画限制)?代码片段(完整:普通 ArkUI 组件 + 沉浸光感)以下 = 生产组件中"普通 ArkUI 组件 + 材质接入"的完整相关代码(约 120 行)。 说明:生产组件在此之上还包含滑动指示器层与手势(PanGesture 拖拽切页、按压反馈、 动画图标),与本问题无关,故省略;如需完整工程可再提供。import { uiMaterial } from '@kit.ArkUI'; import { deviceInfo } from '@kit.BasicServicesKit'; interface MainDestination { index: number; outlineSymbol: Resource; fillSymbol: Resource; label: string; } @ComponentV2 export struct BottomNav { @Param selectedIndex: number = 0 @Event onSelect: (index: number) => void = () => {} @Local materialAvailable: boolean = false private readonly mainDestinations: MainDestination[] = [ { index: 0, outlineSymbol: $r('sys.symbol.message'), fillSymbol: $r('sys.symbol.message_fill'), label: 'Chat' }, { index: 1, outlineSymbol: $r('sys.symbol.person_crop_circle_fill_1'), fillSymbol: $r('sys.symbol.person_crop_circle_fill_1'), label: 'Contacts' }, { index: 2, outlineSymbol: $r('sys.symbol.gearshape'), fillSymbol: $r('sys.symbol.gearshape_fill'), label: 'Settings' } ]; private immersiveMaterial: uiMaterial.ImmersiveMaterial | undefined = undefined; aboutToAppear(): void { try { this.materialAvailable = deviceInfo.apiAvailable('26.0.0'); if (this.materialAvailable) { const info = uiMaterial.getMaterialInfo(); this.materialAvailable = info.state !== uiMaterial.MaterialState.DISABLE; } this.immersiveMaterial = this.materialAvailable ? new uiMaterial.ImmersiveMaterial({ interactive: true, lightEffect: { color: undefined } // 注:曾显式设置 style(ULTRA_THIN/THIN/REGULAR…)逐档测试,均无视觉差异 }) : undefined; } catch (err) { this.materialAvailable = false; this.immersiveMaterial = undefined; } } private surfaceFallbackColor(): ResourceColor { // 材质可用时透明(不遮挡材质);不可用时回退半透明浅底 return this.materialAvailable ? Color.Transparent : $r('sys.color.comp_background_tertiary'); } @Builder DestinationButton(d: MainDestination) { Column({ space: 2 }) { SymbolGlyph(this.selectedIndex === d.index ? d.fillSymbol : d.outlineSymbol) .fontSize(22) .fontColor([this.selectedIndex === d.index ? $r('sys.color.icon_emphasize') : $r('sys.color.icon_primary')]) Text(d.label) .fontSize(10) .fontColor(this.selectedIndex === d.index ? $r('sys.color.icon_emphasize') : $r('sys.color.icon_primary')) } .justifyContent(FlexAlign.Center) .layoutWeight(1) .height('100%') .backgroundColor(Color.Transparent) .onClick(() => { this.onSelect(d.index); }) .accessibilityGroup(true) .accessibilityText(d.label) .accessibilitySelected(this.selectedIndex === d.index) } build() { // 普通 ArkUI 组件:透明全宽 Row 宿主,仅定位两个"普通容器表面" Row({ space: 12 }) { // 表面 1:主胶囊(共享材质实例) Stack() { Row() { ForEach(this.mainDestinations, (d: MainDestination) => { this.DestinationButton(d) }, (d: MainDestination) => `${d.index}`) } .width('100%') .height('100%') } .layoutWeight(1) .height(56) // 普通容器 + 普通属性 .borderRadius(28) .clip(true) .shadow({ radius: 24, color: 'rgba(0,0,0,0.16)', offsetX: 0, offsetY: 6 }) .backgroundColor(this.surfaceFallbackColor()) // ← 写在 systemMaterial 之前(官方顺序) .systemMaterial(this.immersiveMaterial!) // ← 通用属性接入沉浸式系统材质 // 表面 2:独立圆形(同一材质实例) Stack() { Stack() { Text('A').fontSize(22).fontWeight(FontWeight.Medium).fontColor(Color.White) } .alignContent(Alignment.Center) .width(44) .height(44) .borderRadius(22) .backgroundColor('#0A59F7') } .alignContent(Alignment.Center) .width(56) .height(56) .borderRadius(28) .clip(true) .shadow({ radius: 24, color: 'rgba(0,0,0,0.16)', offsetX: 0, offsetY: 6 }) .backgroundColor(this.surfaceFallbackColor()) .systemMaterial(this.immersiveMaterial!) .onClick(() => { this.onSelect(3); }) .accessibilityGroup(true) .accessibilityText('Profile') } .width('100%') .padding({ left: 20, right: 20 }) .margin({ bottom: this.systemInsetVp() + 8 }) // 底部安全区留白 .backgroundColor(Color.Transparent) .hitTestBehavior(HitTestMode.Transparent) } }结构说明(避免"组件不普通"的误判):全程仅使用 Stack/Row/Column/Text/SymbolGlyph + 通用属性(width/height/borderRadius/clip/shadow/backgroundColor/onClick/accessibility);唯一与系统的耦合点 = 表面的 .backgroundColor(Color.Transparent) 与 .systemMaterial(...);两个表面共享一个 uiMaterial.ImmersiveMaterial 实例(aboutToAppear 中创建)。总结:就是我在修复一个问题终于修复成功的时候然后突然发现主界面底部胶囊退化,让我非常摸不着头脑,我修改别的东西为什么会影响到底部胶囊。想来想去,唯一怀疑的线索也只有昨天下午进行的一次系统更新。

评论34

浏览 931

发布于2026-08-30 02:06
半本前瞻
|
技术支持
点赞1
回复于2026-08-31 01:24
几个上线的元服务,付费推广,不论是按点击付费,还是按添加桌面付费,消耗完费用后,都没有任何效果,而且在所有的可以查询页面里都没有数据能支撑消耗的费用。很奇怪,这种付费推广有什么意义?甚至连钱花到哪里都说不清楚。请问如何查询,如何推广?注意,是所有能点击的页面都看了半天找不到任何数据支撑来计量消耗的费用。

评论4

浏览 38

发布于6小时前
大家好,我们在 HarmonyOS 上用 Flutter + ArkTS 做蓝牙设备后台代扫,遇到跨进程无法复用 FlutterEngine 的问题,想请教官方推荐做法。【场景】应用被划掉、界面进程不在时,系统回调 PartnerAgentExtensionAbility.onDeviceDiscovered。我们在这个回调所在进程里创建一个无界面的 FlutterEngine,执行 Dart 后台逻辑,连接蓝牙并处理数据。用户再点击桌面图标时,希望:1. 如果后台那台 FlutterEngine 还在,EntryAbility 直接复用它来渲染 Flutter UI。2. 如果不在,再创建一台新引擎。3. 不要两台引擎同时持有同一条蓝牙连接,也不要两边同时改同一份业务数据。【实际现象】module.json5 里没有配置独立进程,但系统仍把两个 Ability 放到了不同进程:- 界面:com.example.validation_app,里面是 EntryAbility- 代扫:com.example.validation_app:partnerAgent,里面是 PartnerAgentExtensionAbility 和后台 FlutterEngine代扫进程还活着的时候,再点击图标,主进程里的 FlutterEngineCache 是空的,EntryAbility 只能再新建一台引擎。此时代扫进程里的引擎并没有退出,两台引擎同时存在。【已经尝试过】1. 代扫进程创建 FlutterEngine 后放入 FlutterEngineCache。2. EntryAbility 重写 getCachedEngineId(),缓存里有就复用,没有就新建。3. 结果主进程始终查不到 :partnerAgent 进程里的引擎。我们的理解是:FlutterEngineCache 只在当前进程有效。IPC/RPC 可以传业务数据和远程代理,不能把 FlutterEngine、Dart isolate、Native Shell 交给另一个进程的 FlutterView。参考文档:https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/ipc-rpc-development-guideline?docScope=all另外,两台引擎同时活着时,还会抢资源:- 蓝牙:两个进程各有一套 FlutterBluePlus。后台已经连着设备时,前台再扫描或连接同一设备,会出现抢连接、超时,或者连接状态对不上。- 数据:事件文件和 Preferences 是两个进程一起读写的。写入方式是先读出整份内容再整体覆盖,没有跨进程锁,可能互相覆盖,造成记录丢失或状态不一致。【环境】- Flutter for HarmonyOS- compileSdkVersion:26.0.0.105- PartnerAgent API:API 23- Extension 类型:partnerAgent- 应用形态:Flutter + ArkTS【想请教】1. PartnerAgentExtensionAbility 是否固定运行在 :partnerAgent 进程?能否通过配置和 EntryAbility 跑在同一个进程?2. HarmonyOS 是否支持把一个进程里的 FlutterEngine、Dart isolate 或 Flutter Native Shell 交给另一个进程的 FlutterView 渲染?3. 如果引擎不能跨进程复用,怎样避免用户点击后又创建一台引擎,同时后台那台还活着?4. 官方推荐是不是:代扫进程保留后台引擎,EntryAbility 主进程单独创建 UI 引擎,两边只用 IPC/RPC、Preferences 或数据库同步状态?5. 后台进程已经持有蓝牙连接时,前台进程应该怎样使用这条连接,避免重复连接和数据冲突?6. 是否有 PartnerAgent 与 Flutter 一起使用的官方示例或推荐架构?

评论5

浏览 31

发布于7小时前
AI助手
|
推荐答复
AI 生成内容,仅供参考
您遇到的跨进程 FlutterEngine 无法复用的问题,根源在于 HarmonyOS 的进程模型设计与 Flutter 引擎的进程绑定特性。以下逐一回答您的六个问题,并给出推荐架构。一、PartnerAgentExtensionAbility 的进程模型PartnerAgentExtensionAbility 固定运行在独立进程中,进程名格式为 包名:partnerAgent。这是由系统侧的融合短距服务子系统决定的:当已注册的伙伴设备被蓝牙 BLE 扫描或蓝牙连接发现后,系统会拉起 PartnerAgentExtensionAbility 进程,并通过 onDeviceDiscovered 接口通知应用。该进程被激活后会保持运行约 3 分钟(时间随新的通知刷新)。PartnerAgentExtensionAbility 不属于 UIExtensionAbility 的派生类,因此 module.json5 中的 extensionProcessMode 字段对其不生效。它也无法通过 isolationProcess 或 process 字段配置为与 EntryAbility 共进程。系统的进程模型概述明确指出:UIAbility 和部分 ExtensionAbility(如 ServiceExtensionAbility、DataShareExtensionAbility)默认运行在主进程,而 PartnerAgentExtensionAbility 由系统服务管理其独立进程的生命周期,不支持开发者自行更改其进程归属。结论:PartnerAgentExtensionAbility 无法与 EntryAbility 运行在同一个进程。二、FlutterEngine 跨進程复用的可行性HarmonyOS 不支持将一个进程中的 FlutterEngine、Dart isolate 或 Flutter Native Shell 交给另一个进程的 FlutterView 进行渲染。原因如下:FlutterEngine 在 HarmonyOS 上的实现(Flutter OHOS)中,核心对象包括 FlutterEngine(封装 DartExecutor、系统通道、插件注册表)、FlutterView(渲染容器,绑定 XComponent)、FlutterRenderer(纹理管理)等。这些对象全部依赖当前进程的内存空间、Dart VM 实例和图形子系统上下文,是进程内的强引用对象。FlutterEngineCache 本质上是一个进程内的静态单例 Map,仅在当前进程的内存中有效。IPC/RPC 机制(基于 Binder 驱动)只能传递可序列化的数据(Parcel 中的基本类型、字符串、数组等)和远程代理对象(IRemoteObject),无法传递 FlutterEngine 这类包含原生指针、Dart VM 堆地址、GPU Surface 句柄的进程内对象。结论:引擎不能跨进程复用,您的理解是正确的。三、避免重复创建引擎的推荐架构既然引擎无法跨进程复用,推荐采用"双引擎 + IPC 同步"架构:代扫进程(:partnerAgent):保留后台 FlutterEngine,负责蓝牙连接、数据采集等后台逻辑。此引擎无界面,仅运行 Dart 业务代码。主进程(com.example.validation_app):EntryAbility 创建独立的 UI FlutterEngine,负责界面渲染和用户交互。两个进程之间通过 IPC/RPC 或公共事件机制同步状态,而非尝试共享引擎实例。为避免用户点击桌面图标时主进程无谓地新建引擎,可在 EntryAbility 启动时先通过 IPC 查询代扫进程是否存活及其状态。如果代扫进程存活且已有后台引擎在运行,主进程只需创建 UI 引擎并从代扫进程拉取当前状态数据即可;如果代扫进程已销毁,主进程创建 UI 引擎并自行处理蓝牙逻辑。以下是关键代码示例:代扫进程侧 —— PartnerAgentExtensionAbility 中创建后台引擎并通过公共事件通知主进程:import { PartnerAgentExtensionAbility } from '@kit.ConnectivityKit'; import { partnerAgent } from '@kit.ConnectivityKit'; import { commonEventManager } from '@kit.BasicServicesKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { FlutterEngine, FlutterEngineGroup } from '@ohos/flutter_ohos'; import { common } from '@kit.AbilityKit'; // 后台引擎状态标识 const BG_ENGINE_READY_EVENT: string = 'com.example.validation_app.BG_ENGINE_READY'; const BG_STATE_QUERY_EVENT: string = 'com.example.validation_app.BG_STATE_QUERY'; export default class PartnerAgentAbility extends PartnerAgentExtensionAbility { private bgEngine: FlutterEngine | null = null; private engineGroup: FlutterEngineGroup | null = null; onDeviceDiscovered(deviceAddress: partnerAgent.PartnerDeviceAddress): void { console.info(`[PartnerAgent] onDeviceDiscovered: ${deviceAddress.bluetoothAddress?.address}`); // 首次发现设备时创建后台引擎 if (this.bgEngine === null) { this.createBackgroundEngine(); } // 通过 MethodChannel 通知 Dart 侧执行蓝牙连接逻辑 // ...具体蓝牙连接代码由 Dart 侧处理 } private createBackgroundEngine(): void { try { const context = this.context as common.Context; this.engineGroup = new FlutterEngineGroup(context); this.engineGroup.createEngine(context, null).then((engine: FlutterEngine) => { engine.init(context, null, false).then(() => { this.bgEngine = engine; console.info('[PartnerAgent] 后台引擎创建成功'); // 发布公共事件通知主进程后台引擎已就绪 this.notifyBgEngineReady(); }).catch((err: BusinessError) => { console.error(`[PartnerAgent] 引擎初始化失败: ${err.code} ${err.message}`); }); }).catch((err: BusinessError) => { console.error(`[PartnerAgent] 引擎创建失败: ${err.code} ${err.message}`); }); } catch (err) { console.error(`[PartnerAgent] 创建后台引擎异常: ${(err as BusinessError).code}`); } } private notifyBgEngineReady(): void { let publishData: commonEventManager.CommonEventPublishData = { code: 1, data: 'bg_engine_ready', }; commonEventManager.publish(BG_ENGINE_READY_EVENT, publishData, (err: BusinessError) => { if (err.code) { console.error(`[PartnerAgent] 发布事件失败: ${err.code} ${err.message}`); } else { console.info('[PartnerAgent] 后台引擎就绪事件已发布'); } }); } onDestroyWithReason(reason: partnerAgent.PartnerAgentExtensionAbilityDestroyReason): void { console.info(`[PartnerAgent] onDestroyWithReason: ${reason}`); // 销毁后台引擎,释放蓝牙资源 this.bgEngine?.destroy(); this.bgEngine = null; } }主进程侧 —— EntryAbility 中创建 UI 引擎并监听后台状态:import { ExclusiveAppComponent, FlutterManager } from '@ohos/flutter_ohos'; import { UIAbility } from '@kit.AbilityKit'; import { AbilityConstant } from '@kit.AbilityKit'; import { Want } from '@kit.AbilityKit'; import { window } from '@kit.WindowKit'; import { commonEventManager } from '@kit.BasicServicesKit'; import { BusinessError } from '@kit.BasicServicesKit'; const BG_ENGINE_READY_EVENT: string = 'com.example.validation_app.BG_ENGINE_READY'; // 后台引擎状态 class BgEngineState { isReady: boolean = false; connectedDevice: string = ''; } export default class EntryAbility extends UIAbility implements ExclusiveAppComponent<UIAbility> { static app?: EntryAbility; private bgState: BgEngineState = new BgEngineState(); detachFromFlutterEngine(): void { } getAppComponent(): UIAbility { return this; } onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { FlutterManager.getInstance().pushUIAbility(this); EntryAbility.app = this; // 订阅后台引擎就绪事件 this.subscribeBgEngineReady(); } private subscribeBgEngineReady(): void { let subscriberInfo: commonEventManager.CommonEventSubscribeInfo = { events: [BG_ENGINE_READY_EVENT], }; commonEventManager.createSubscriber(subscriberInfo, (err: BusinessError, subscriber) => { if (err.code || subscriber === null) { console.error(`[EntryAbility] 创建订阅者失败: ${err.code} ${err.message}`); return; } commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => { if (err.code) { console.error(`[EntryAbility] 订阅回调错误: ${err.code} ${err.message}`); return; } // 后台引擎已就绪,标记状态 this.bgState.isReady = true; console.info(`[EntryAbility] 收到后台引擎就绪通知: ${data.data}`); // 后续通过 IPC 或公共事件向后台引擎请求当前蓝牙连接状态 }); }); } onWindowStageCreate(windowStage: window.WindowStage): void { windowStage.getMainWindowSync().setWindowLayoutFullScreen(true); FlutterManager.getInstance().pushWindowStage(this, windowStage); // 主进程独立创建 UI 引擎,不依赖代扫进程的引擎 windowStage.loadContent('pages/MainPage'); } onDestroy(): void | Promise<void> { FlutterManager.getInstance().popUIAbility(this); EntryAbility.app = undefined; } onWindowStageDestroy(): void { FlutterManager.getInstance().popWindowStage(this); } }四、蓝牙连接冲突的避免策略蓝牙连接必须由单一进程持有,推荐由代扫进程独占蓝牙连接,主进程不直接操作蓝牙 API。具体策略:代扫进程持有唯一的蓝牙 GATT 连接,所有蓝牙数据读写均在该进程内完成。主进程需要蓝牙数据时,通过公共事件或 IPC 向代扫进程发起请求,代扫进程处理后通过公共事件返回结果。主进程不调用 ble.createGattClientDevice 或 gattClient.connect(),避免两个进程争抢同一设备的连接句柄。HarmonyOS 蓝牙模块的 FAQ 中也提到:使用相同 UUID 连接参数时,若应用 A 已成功连接蓝牙设备,应用 B 再次尝试连接会报错或异常。虽然这里是指不同应用,但同一应用的不同进程也会面临类似的底层资源竞争问题。以下是跨进程蓝牙状态同步的示例:代扫进程发布蓝牙状态事件:import { commonEventManager } from '@kit.BasicServicesKit'; import { BusinessError } from '@kit.BasicServicesKit'; const BT_STATE_EVENT: string = 'com.example.validation_app.BT_STATE_UPDATE'; // 蓝牙状态数据模型 class BluetoothStateData { deviceId: string = ''; isConnected: boolean = false; lastData: string = ''; } function publishBluetoothState(state: BluetoothStateData): void { let publishData: commonEventManager.CommonEventPublishData = { code: state.isConnected ? 1 : 0, data: JSON.stringify({ deviceId: state.deviceId, lastData: state.lastData, } as Record<string, string>), }; commonEventManager.publish(BT_STATE_EVENT, publishData, (err: BusinessError) => { if (err.code) { console.error(`[PartnerAgent] 发布蓝牙状态失败: ${err.code} ${err.message}`); } }); }主进程订阅蓝牙状态事件并更新 UI:import { commonEventManager } from '@kit.BasicServicesKit'; import { BusinessError } from '@kit.BasicServicesKit'; const BT_STATE_EVENT: string = 'com.example.validation_app.BT_STATE_UPDATE'; // 主进程接收的蓝牙状态模型 class ReceivedBtState { deviceId: string = ''; isConnected: boolean = false; lastData: string = ''; } function subscribeBluetoothState(onUpdate: (state: ReceivedBtState) => void): void { let subscriberInfo: commonEventManager.CommonEventSubscribeInfo = { events: [BT_STATE_EVENT], }; commonEventManager.createSubscriber(subscriberInfo, (err: BusinessError, subscriber) => { if (err.code || subscriber === null) { console.error(`[EntryAbility] 创建蓝牙状态订阅者失败: ${err.code}`); return; } commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => { if (err.code) { return; } let state: ReceivedBtState = new ReceivedBtState(); state.isConnected = data.code === 1; let parsed: Object | null = JSON.parse(data.data); if (parsed !== null) { let obj = parsed as Record<string, string>; state.deviceId = obj['deviceId'] ?? ''; state.lastData = obj['lastData'] ?? ''; } onUpdate(state); }); }); }五、数据冲突的避免策略您描述的"先读出整份内容再整体覆盖"的写入方式在多进程并发场景下确实会产生竞态条件。解决方案有两种:方案一:使用 GSKV 跨進程共享 Preferences(API 18+)。从 API 18 起,Preferences 新增了跨进程共享键值(GSKV)存储模式,允许同一应用的不同进程安全地访问同一份 Preferences 数据。使用时需指定存储模式为多进程共享模式。方案二:集中写入。所有业务数据的写入操作统一由代扫进程执行,主进程只读取数据或通过 IPC 向代扫进程发送写入请求。这样可以完全避免两个进程同时写入同一份数据。推荐方案二,因为它同时解决了蓝牙和数据两个资源的冲突问题——代扫进程作为唯一的"业务执行者",主进程仅作为"UI 展示者和指令发送者"。六、关于官方示例目前官方提供了 PartnerAgentExtensionAbility 的开发指南和完整示例(包含 EntryAbility + PartnerAgentAbility 的工程结构),以及 Flutter OHOS 的多引擎开发指导(FlutterEngineGroup 使用方式和 FlutterEngineCache 缓存机制)。但 PartnerAgent 与 Flutter 联合使用的官方端到端示例尚未提供。基于现有官方文档和 Flutter OHOS 架构原理,推荐的架构总结如下:层面代扫进程(:partnerAgent)主进程FlutterEngine后台无界面引擎,运行 Dart 业务逻辑UI 引擎,负责界面渲染蓝牙独占 GATT 连接、扫描、数据读写不直接操作蓝牙 API数据写入独占业务数据写入(文件、Preferences)通过 IPC 发送写入请求,不直接写进程间通信发布公共事件、响应 IPC 请求订阅公共事件、发起 IPC 请求引擎生命周期随 PartnerAgent 进程生命周期管理随 EntryAbility 生命周期管理这种架构下,两个引擎各司其职,不会出现两台引擎同时持有同一条蓝牙连接或同时改同一份数据的情况。核心原则是:代扫进程是"业务执行者",主进程是"UI 展示者和指令发送者",两者通过公共事件或 IPC 协调状态。
点赞1
回复于6小时前
DevEco Studio正常使用过程中,不定时地出现占用CPU过高,飙升到100%,导致电脑卡住,完全动不了,同时I/O占用也飙升有解决方法吗?Windows10 系统,版本如下

评论6

浏览 37

发布于7小时前
如何实现组件边缘的折射效果 背景纯透明 仅边缘折射效果 并且可以根据背景的变化实时进行预览的效果 这种相果 也就是苹果的液态玻璃效果 如何在鸿蒙当中使用arkui去实现液态玻璃的效果 能否完全复刻苹果的液态玻璃效果

评论49

浏览 627

发布于2026-09-05 02:57
云云
|
采纳答复
点赞4
回复于2026-09-10 06:57
在HarmonyOS应用中,长列表滚动时出现卡顿,怀疑是列表控件或子控件渲染开销过大。想请教如何排查是列表布局、组件复用、图片加载还是动画造成的性能问题,有哪些工具和指标可以定位?

评论8

浏览 43

发布于7小时前
快乐打工人
|
技术支持
点赞
回复于5小时前
在顶部有个标题区域,用 @Builder 封装成了 titleBuilder,这样就通过接收一个字符串参数来更新标题,但在实际场景中发现子组件更新后,this.title 确实变了,但页面上标题文字没有任何变化。 @State title: string = ''; .onClick(() => { this.title = '新标题' + Math.random(); })代码就上面这样,很简单,为什么会不更新了,我看了@Builder的用法,应该没问题呢。

评论6

浏览 22

发布于7小时前
在开发鸿蒙自定义控件时,遇到不同分辨率设备下布局比例不一致的问题,想请教如何通过布局约束或尺寸计算来保持控件比例一致?

评论8

浏览 32

发布于7小时前
用 HdsTabs 做底部 Tab,默认看起来像有"包边"。示例代码如下所示:HdsTabs({ index: this.currentTabIndex, controller: this.tabsController }) { TabContent() { } .tabBar(this.TabTextBuilder(this.tabTitles[0], 0)) // …… } .barFloatingStyle({ barWidth: { smallWidth: 280, mediumWidth: 300, largeWidth: 320 }, barBottomMargin: 8, gradientMask: { maskColor: Color.Transparent }, lightColor: Color.Transparent, systemMaterialEffect: { materialType: hdsMaterial.MaterialType.IMMERSIVE, materialLevel: hdsMaterial.MaterialLevel.EXQUISITE } }) .barPosition(BarPosition.End) .barOverlap(true) .barBackgroundColor(Color.Transparent) .barBackgroundBlurStyle(BlurStyle.NONE) .divider({ mode: DividerMode.NONE })最终的效果是:期望的效果是,无边框线的:

评论42

浏览 245

发布于2026-09-25 09:17
云上
|
采纳答复
这个问题的根因楼上老师们已经定位了:那圈"包边"是 systemMaterialEffect 沉浸光感材质(IMMERSIVE)自带的边缘高光,和毛玻璃是捆绑效果,三档 materialLevel 只是强度差异。我补充一个还没有人提到的中间路线——用低层 API 自己叠材质,把"系统毛玻璃质感"和"边缘光感"真正解耦:思路:背景模糊用 windowBlur / backgroundEffect,而不是 barBackgroundBlurStylebarBackgroundBlurStyle 的 COMPONENT_THIN 档观感确实比系统材质弱一截(楼主实测也证实了)。想要更接近 EXQUISITE 的磨砂质感,可以试 backgroundEffect,它提供可调参数,能逼近系统材质的观感:.barBackgroundColor(Color.Transparent) .backgroundEffect({ radius: 40, // 模糊半径,调到接近 EXQUISITE 的雾面感 saturation: 1.2, // 饱和度略提,模拟系统材质的通透感 brightness: 1.05, // 轻微提亮 colorOptions: [{ color: '#80FFFFFF', cornerRadius: 28 }] // 白色薄纱 + 圆角 })这个路径出来的效果介于 COMPONENT_THIN 和系统材质之间,且不会带边缘描边,多数设计稿能对上。如果必须要系统材质:换 MaterialType 而不是降档补一个实测细节:MaterialType.IMMERSIVE(沉浸光感)是"毛玻璃+边缘光"捆绑的来源,但 hdsMaterial 里还有其他 materialType(如标准材质),不同 type 的边缘表现不一样。可以试把 materialType 换掉、materialLevel 保持 EXQUISITE,部分 type 下毛玻璃质感保留而边缘高光明显减弱,这比无脑降到 SMOOTH 更接近"只要毛玻璃"的目标。具体各 type 的视觉差异建议在真机上对照 Demo 各跑一遍(模拟器的材质渲染和真机偏差较大)。最后说下取舍楼主自己实测的结论(两者不可兼得)在"只用 systemMaterialEffect 预设"的前提下成立;但走 backgroundEffect 自绘这条路,毛玻璃 + 无边框是可以同时拿到的,只是放弃了系统材质的动态光影(点光源、按压流光)。如果产品要求的是"静态毛玻璃无包边",自绘完全够用;如果要求系统级动态光影,那只能接受边缘光或等官方提供解耦参数,可以顺手在 DevEco Studio 的 Send Feedback 里提个需求。x
点赞1
回复于2026-09-30 07:46

我要提问题

月度答复贡献榜
用户头像
橙动创意
回帖889
粉丝54
关注
用户头像
心系天下
回帖767
粉丝15
关注
用户头像
蓝瘦的蜕变
回帖377
粉丝117
关注
用户头像
慢行
回帖308
粉丝18
关注
用户头像
不羁的木木
回帖237
粉丝36
关注
邀您回答
热门标签
1

HarmonyOS 5

2

HarmonyOS 6

3

DevEco Studio

4

UI

5

HarmonyOS

6

ArkUI (方舟UI框架)

7

HarmonyOS 7

8

App开发

9

Ability框架

了解社区公约,与您携手共创和谐专业的开发者社区。
在 App 中查看