Harmony OS 后台任务-长时任务

二、长时任务

传送门

1.为什么使用长时任务

  • 需要长时间在后台运行, 并且需要用户可以感知( 音频播放, 导航 )的事件
  • 防止一段时间以后, 因为 App 被挂起, 导致系统管控导致运行结束

2.长时任务类型

在这里插入图片描述

3.长时任务限制

  • 一个应用的同一个 UIiAbility 只能同时申请一个长时任务
  • 你要根据你不同的长时任务类型, 去 module.json5 文件中申请不同的权限
  • 所有的长时任务都需要 want 对象, 因为他需要拉起 Ability
  • api
    • startBackgroundRunning 申请长时任务
    • stopBackgroundRunning 取消长时任务

4.长时任务示例(音频播放)

4.1 权限配置

  • 申请权限 ohos.permission.KEEP_BACKGROUND_RUNNING

    • src > main > module.json5

        "requestPermissions": [
          { "name": "ohos.permission.KEEP_BACKGROUND_RUNNING" }
        ],
      
  • 声明后台模式类型,参照长时任务类型

    • src > main > module.json5 配置 backgroundModes

        {
          "module": {
            "name": "entry",
            "type": "entry",
            "description": "$string:module_desc",
            "mainElement": "EntryAbility",
            // 权限
            "requestPermissions": [
              { "name": "ohos.permission.KEEP_BACKGROUND_RUNNING" }
            ],
            "deviceTypes": [
              "phone",
              "tablet",
              "2in1"
            ],
            "deliveryWithInstall": true,
            "installationFree": false,
            "pages": "$profile:main_pages",
            "abilities": [
              {
                "name": "EntryAbility",
                "srcEntry": "./ets/entryability/EntryAbility.ets",
                "description": "$string:EntryAbility_desc",
                // 后台模式类型
                "backgroundModes":[
                  "audioPlayback"
                ],
                "icon": "$media:layered_image",
                "label": "$string:EntryAbility_label",
                "startWindowIcon": "$media:startIcon",
                "startWindowBackground": "$color:start_window_background",
                "exported": true,
                "skills": [
                  {
                    "entities": [
                      "entity.system.home"
                    ],
                    "actions": [
                      "action.system.home"
                    ]
                  }
                ]
              }
            ]
          }
        }
      

4.2 导入模块

import { media } from '@kit.MediaKit'
import { common, WantAgent, wantAgent } from '@kit.AbilityKit'
import { backgroundTaskManager } from '@kit.BackgroundTasksKit'
import { BusinessError } from '@kit.BasicServicesKit'
import { avSession } from '@kit.AVSessionKit'

4.3 音频播放

  // 创建变量
  AVPlayer: media.AVPlayer = Object()

  async audioPlay() {
    const avplayer = await media.createAVPlayer()

    this.setStateEventHandler(avplayer)
    // 传递 音频 url 地址
    avplayer.url = ''
    // 复制给私有变量
    this.AVPlayer = avplayer

    //  音乐在后台播放需要有音乐控制器 AVSession
    // const session = await avSession.createAVSession(上下文, 描述, 类型)
    const session = await avSession.createAVSession(this.context, '音乐播放测试', 'audio')
    // 给 session 注册一些事件来完成不同的动作
    // 如果你想让他完整的使用, 那么你的 AVPlayer 的状态机( 注册机需要调用完整 ) ,通过方法 setStateEventHandler() 
    session.on('play', () => {
      this.AVPlayer.play()
    })

    session.on('pause', () => {
      this.AVPlayer.pause()
    })
    // 让当前 session 执行起来
    session.activate()
  }

4.4 状态机

  // 状态机实际上就是监听 AVPlayer 的状态变化, 然后做对应的动作
  // 给当前 AVPlayer 绑定各种事件
  setStateEventHandler(avplayer: media.AVPlayer) {
    avplayer.on('stateChange', (state: string) => {
      if (state === 'idle') {
        // 注销当前实例( 把当前播放器注销掉, 不管将来发生什么, 你如果不主动播放, 都不会播放了 )
        // Care : 你切换下一首歌的时候, 也会进入一次 idle
        this.player.release()
        //
        // // 取消长时任务( 因为一个应用的一个Ability 只能同时申请一个长时任务, 所以不需要 id , 我们直接取消任务即可 )
        backgroundTaskManager.stopBackgroundRunning(this.context)
      }

      if (state === 'initialized') {
        // 表示音频播放器初始化成功
        // 在这来开始准备音频播放
        // avplayer.prepare()
      }

      if (state === 'prepared') {

      }

      if (state === 'playing') {

      }

      if (state === 'paused') {

      }
    })
  }

4.5 开启长时任务

// 点击事件-启动长时任务-开启音频播放
clickHandler() {
  // 需要申请一个长时任务
  // 准备一个 want 对象
  const wantAgentInfo: wantAgent.WantAgentInfo = {
    wants: [
      {
        bundleName: 'com.example.mytask',
        abilityName: 'EntryAbility'
      }
    ],
    // 表示点击通知栏的时候的动作( 我这里选择的事 拉起 Ability )
    actionType: wantAgent.OperationType.START_ABILITY,
    // 自己定义的一个私有值
    requestCode: 10086,
    // 点击以后执行的动作
    actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
  }

  // 生成通知内容
  wantAgent
    .getWantAgent(wantAgentInfo)
    .then((data: WantAgent) => {
      // 申请长时任务即可
      // backgroundTaskManager.startBackgroundRunning(当前的上下文, 后台任务类型, want 对象)
      backgroundTaskManager
        .startBackgroundRunning(
          this.context,
          backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
          data
        )
        .then(() => {
          // 在这里面表示长时任务申请成功
          console.log('DeepCode => 长时任务申请成功')
          // 可以执行你需要的长时任务了( 目前: 播放音乐 )
          this.AVPlayer.play()
            .then((data)=>{
              console.log('wuwuwu play success =>', JSON.stringify(data));
            })
            .catch((err: Error) => {
            console.log('wuwuwu play =>', JSON.stringify(err));
          })
        })
        .catch((err: BusinessError) => {
          // 表示长时任务申请失败
          console.log('wuwuwu => 长时任务申请失败, 失败原因 ' + JSON.stringify(err))
        })
    })
    .catch((err: BusinessError) => {
      console.log('wuwuwu => 创建 want 信息对象失败, 失败原因 : ' + JSON.stringify(err))
    })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值