HarmonyOS鸿蒙Next中在自定义扫码界面时,退到后台再回到前台,扫码停止该如何解决

HarmonyOS鸿蒙Next中在自定义扫码界面时,退到后台再回到前台,扫码停止该如何解决

【问题现象】

Tabs组件管理的首页面是自定义扫码界面,开启相机进行扫描,然后手动退到后台,回到前台后无法继续扫描,页面静止不动。

问题代码如下:

@Entry
@Component
struct MainPage {
  build() {
    Tabs({
      barPosition: BarPosition.End
    }) {
      TabContent() {
        CustomScanPage()
      }
    }
  }
}
export struct CustomScanPage {
  onPageShow(): void {
    this.initCustomScan()
  }
  onPageHide(): void{
    this.releaseCustomScan();
  }
  //初始化扫码资源
  initCustomScan() {
    customScan.init();
    customScan.start().then((scanResult: Array<scanBarcode.ScanResult>) => {
    //扫码结果处理
    }).catch((error: BusinessError) => {
    //错误信息处理
    });
  }
  // 释放扫码资源
  releaseCustomScan() {
    customScan.stop();
    customScan.release();
   }
}

【背景知识】

(1)相机切换后台再切回来,必须要重新初始化相机才可以。因为切后台,相机资源被全部回收。

(2)自定义扫码提供了扫码相机流控制接口,支持扫码界面自定义并实现基本的扫码功能。您可根据相应场景来开启、暂停和释放相机流,还可根据相应的光线条件来控制闪光灯的打开和关闭,便于用户进行扫码。

扫码时序图如下:

点击放大

自定义扫码参考文档

【定位思路】

从问题代码可以看出工程中希望在onPageShow和onPageHide方法内实现扫码的初始化和释放逻辑,但是onPageShow和onPageHide方法属于页面生命周期方法,Tabs是容器组件,所管理的CustomScanPage页面属于子组件,所以不会触发页面的生命周期方法。

(1)组件触发的生命周期方法:

  • aboutToAppear()
  • aboutToDisappear()
  • aboutToReuse()

(2)页面触发的生命周期方法:

  • onPageShow()
  • onPageHide()
  • onBackPress()

通过以上分析,子组件CustomScanPage页面不会触发onPageShow和onPageHide方法,导致前后台切换时不会重新初始化和释放相机资源,再进入前台后扫码界面静止。为了实现进入后台调用release接口进行释放扫码资源,进入前台调用init接口初始化扫码资源的目标,需要通过注册uiObserver方法监听自定义扫码页面是否显示。

【解决方案】

1. 自定义组件监听页面生命周期

(1)初始化监听方法

//初始化监听方法
  listener: (info: uiObserver.RouterPageInfo) => void = (info: uiObserver.RouterPageInfo) => {
    let routerInfo: uiObserver.RouterPageInfo | undefined = this.queryRouterPageInfo();
    if (info.pageId == routerInfo?.pageId) {
      if (info.state == uiObserver.RouterPageState.ON_PAGE_SHOW) {
        this.onPageShow()
      } else if (info.state == uiObserver.RouterPageState.ON_PAGE_HIDE) {
        this.onPageHide()
      }
    }
  }

(2)在aboutToAppear()方法中注册监听方法

aboutToAppear() {
    //注册监听方法
    let uiObserver: UIObserver = this.getUIContext().getUIObserver();
    uiObserver.on('routerPageUpdate', this.listener);
 }

(3)通过监听触发的方法中实现初始化和销毁逻辑

onPageShow(): void { 
   //在页面显示时初始化自定义扫码资源
   this.initCustomScan()
} 
onPageHide(): void {
   //在页面消失时释放自定义扫码资源
   this.releaseCustomScan();
}

(4)在aboutToDisappear()方法中注销监听方法

aboutToDisappear(): void {
    let uiObserver: UIObserver = this.getUIContext().getUIObserver();
    uiObserver.off('routerPageUpdate', this.listener);
}

【总结】

(1)当前后台切换导致相机功能出现画面静止时,都可以通过每次进入后台先释放相机资源、进入前台再初始化相机资源的方案解决。

(2)Tabs组件管理的页面属于子组件,所以不会触发页面生命周期方法。


更多关于HarmonyOS鸿蒙Next中在自定义扫码界面时,退到后台再回到前台,扫码停止该如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中在自定义扫码界面时,退到后台再回到前台,扫码停止该如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,自定义扫码界面退到后台再回到前台时,扫码停止的问题

在HarmonyOS鸿蒙Next中,自定义扫码界面退到后台再回到前台时,扫码停止的问题,通常是由于生命周期管理导致的。鸿蒙系统的Ability生命周期在切换到后台时会触发onBackground,回到前台时会触发onForeground。在onBackground中,系统会暂停当前页面的活动,包括扫码功能。

要解决此问题,可以在onForeground中重新初始化扫码功能。具体实现如下:

  1. onForeground方法中,检查扫码功能是否已经停止,如果是,则重新启动扫码功能。
  2. 确保在onBackground中正确处理资源的释放,以避免内存泄漏。

示例代码

import { Ability } from '@ohos.application.Ability';
import { Scanner } from '@ohos.scanner';

export default class MainAbility extends Ability {
    private scanner: Scanner | null = null;

    onForeground() {
        super.onForeground();
        if (!this.scanner) {
            this.initScanner();
        }
    }

    onBackground() {
        super.onBackground();
        this.releaseScanner();
    }

    private initScanner() {
        this.scanner = new Scanner();
        // 初始化扫码功能
    }

    private releaseScanner() {
        if (this.scanner) {
            this.scanner.release();
            this.scanner = null;
        }
    }
}

通过这种方式,可以在应用回到前台时重新启动扫码功能,确保用户体验的连续性。

回到顶部