HarmonyOS鸿蒙Next中使用XComponent实现画中画前后台问题

HarmonyOS鸿蒙Next中使用XComponent实现画中画前后台问题 我在后台执行第一次画中画不会生效,除非第二次返回后台才会出现,是因为调用时间太慢问题吗,提前创建可以解决吗

cke_482.png


更多关于HarmonyOS鸿蒙Next中使用XComponent实现画中画前后台问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

【背景知识】

  • 画中画:应用在视频播放、视频会议、视频通话等场景下,可以使用画中画能力将视频内容以小窗(画中画)模式呈现。切换为小窗(画中画)模式后,用户可以进行其他界面操作,提升使用体验。
  • setAutoStartEnabled:基于安全考虑,应用处于后台时不允许通过startPiP启动画中画。针对应用返回后台时需要启动画中画的场景,建议使用setAutoStartEnabled(true)实现自动启动。
  • onBackground:在UIAbility的UI完全不可见之后,系统触发onBackground回调,将UIAbility实例切换至后台状态。开发者可以在该回调中释放UI不可见时的无用资源,例如停止定位功能,以节省系统的资源消耗。

【解决方案】

在应用进入后台应用会被挂起,onBackground()执行时间较短,无法提供足够的时间做一些耗时动作。画中画create、setAutoStartEnabled当应用在前台时就执行,因此在进入页面或者组件的时候,就创建画中画窗口并将setAutoStartEnabled设置为true,在不需要自动启动画中的时候,将setAutoStartEnabled设置为false。

参考示例代码:

aboutToAppear(): void {
    let promise: Promise<PipWindow.PiPController> = PipWindow.create(this.config);
    promise.then((data: PipWindow.PiPController) => {
      this.pipController = data;
      // 开启画中画自动拉起开关
      this.pipController.setAutoStartEnabled(true)
      console.info(`Succeeded in creating pip controller. Data:${data}`);
    }).catch((err: BusinessError) => {
      console.error(`Failed to create pip controller. Cause:${err.code}, message:${err.message}`);
    });
  }

更多关于HarmonyOS鸿蒙Next中使用XComponent实现画中画前后台问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


  1. 文档中画中画切后台打开的功能存在限制:基于安全考虑,应用处于后台时不允许通过startPiP启动画中画。针对应用返回后台时需要启动画中画的场景,建议使用setAutoStartEnabled(true)实现自动启动。

  2. 楼主可以使用setAutoStartEnabled这个方法来实现

let enable: boolean = true;
this.pipController.setAutoStartEnabled(enable);

参考文档:画中画开发概述-在应用程序中使用画中画功能-窗口管理-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者

【背景知识】

[@ohos.PiPWindow](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-pipwindow):该模块提供画中画基础功能,包括判断当前系统是否支持画中画功能,以及创建画中画控制器用于启动或停止画中画等。适用于视频播放、视频通话或视频会议场景下,以小窗(画中画)模式呈现内容。

【参考方案】

可参考实现画中画效果示例,通过媒体服务和ArkUI的基本能力,实现视频播放、手动和自动拉起画中画、画中画窗口控制视频播放和暂停等功能效果。

  • 整个示例用Navigation构建页面,主页面放置五个可点击视频框,点击之后进入视频播放页面。
  • 进入视频播放页面后,有三块区域,最上方的XComponent,中间的画中画控制按钮以及下方的回调信息显示框
  • 点击开启后,应用手动拉起画中画,视频在画中画播放,返回桌面视频依旧画中画播放;点击关闭后,画中画播放的视频返回XComponent播放,同时返回桌面不会拉起画中画。
  • 点击自动拉起画中画后,返回桌面时应用自动拉起画中画,视频画中画播放。
  • 在播放页面进行画中画播放时,XComponent框会提示当前视频正在以画中画播放
  • 回调信息显示框会显示当前状态错误原因以及按钮事件和状态,参考:VideoPlay.ets

系统为防止滥用,禁止应用处于后台时通过startPiP()手动触发画中画;首次返回后台时未正确预加载画中画控制器,导致首次请求失效;未正确使用setAutoStartEnabled(true)实现自动触发机制。

解决方案

1/ 在页面显示阶段提前初始化控制器:

import { PiPWindow } from '@kit.ArkUI';

// 在页面类中声明控制器

private pipController?: PiPWindow.PiPController;

aboutToAppear() {

  const config: PiPWindow.PiPConfiguration = {

    context: getContext(this),

    componentController: this.mXComponentController // XComponent控制器实例

  };

  PiPWindow.create(config).then(controller => {

    this.pipController = controller;

    this.pipController.setAutoStartEnabled(true); // 关键配置

  });

}

2/移除主动调用startPiP()的代码,改用系统自动触发:

// 错误:后台调用会失败

onBackPressed() {

  this.pipController?.startPiP();

}

// 正确做法:依赖setAutoStartEnabled(true)自动触发

3/添加状态监听确保恢复逻辑:

this.pipController?.on('stateChange', (state: PiPWindow.PiPState) => {

  if (state === PiPWindow.PiPState.ENTERED) {

    console.log('画中画已激活');

  } else if (state === PiPWindow.PiPState.RESTORED) {

    console.log('恢复全屏');

  }

});

在HarmonyOS Next中,XComponent通过ArkTS/ArkUI实现画中画功能,支持前后台切换时保持渲染。需使用@ohos.window接口管理窗口层级,通过onWindowStageChange事件监听前后台状态变化,动态调整XComponent的可见性与布局。使用XComponentController控制画面渲染与暂停,确保资源正确释放与恢复。

根据描述,这可能是由于XComponent在首次进入后台时初始化或渲染延迟导致的。建议在应用启动或前台时就提前创建并初始化XComponent组件,确保资源预加载。这样可以避免首次后台切换时的延迟问题,提升画中画的响应速度。同时检查生命周期回调是否正确处理,确保前后台切换时能及时触发组件状态更新。

回到顶部