OpenHarmony应用开发-ServiceAbility组件开发指导

素年锦时静待君丶
发布于 2023-4-10 17:35
浏览
0收藏

版本:v3.2 Beta5

ServiceAbility组件概述

ServiceAbility,即"基于Service模板的Ability",主要用于后台运行任务(如执行音乐播放、文件下载等),不提供用户交互界面。ServiceAbility可由其他应用或PageAbility启动,即使用户切换到其他应用,ServiceAbility仍将在后台继续运行。

ServiceAbility组件配置

与PageAbility类似,ServiceAbility的相关配置在config.json配置文件的"module"对象的"abilities"对象中,与PageAbility的区别在于"type"属性及"backgroundModes"属性。

表1 ServiceAbility部分配置项说明

属性名称

含义

数据类型

是否可缺省

type

表示Ability的类型。取值为"service"时表示该Ability是基于Service模板开发的Ability。

字符串

backgroundModes

表示后台服务的类型,可以为一个服务配置多个后台服务类型。该标签仅适用于service类型的Ability。取值范围如下:

dataTransfer:通过网络/对端设备进行数据下载、备份、分享、传输等业务。

audioPlayback:音频输出业务。

audioRecording:音频输入业务。

pictureInPicture:画中画、小窗口播放视频业务。

voip:音视频电话、VOIP业务。

location:定位、导航业务。

bluetoothInteraction:蓝牙扫描、连接、传输业务。

wifiInteraction:WLAN扫描、连接、传输业务。

screenFetch:录屏、截屏业务。

multiDeviceConnection:多设备互联业务。

字符串数组

可缺省,缺省值为空。

ServiceAbility支持的配置项及详细说明详见​​module对象内部结构​​。

ServiceAbility的生命周期

开发者可以根据业务场景重写生命周期相关接口。ServiceAbility生命周期接口说明见下表。

表1 ServiceAbility生命周期接口说明

接口名

描述

onStart(): void

该方法在创建ServiceAbility的时候调用,用于Service的初始化,在ServiceAbility的整个生命周期只会调用一次。

onCommand(want: Want, startId: number): void

在Service创建完成之后调用,该方法在客户端每次启动该Service时都会调用,开发者可以在该方法中做一些调用统计、初始化类的操作。

onConnect(want: Want): rpc.RemoteObject

在连接ServiceAbility时调用。

onDisconnect(want: Want): void

在与已连接的ServiceAbility断开连接时调用。

onStop(): void

在ServiceAbility销毁时调用。开发者应通过实现此方法来清理资源,如关闭线程、注册的侦听器等。

创建ServiceAbility

  1. 创建ServiceAbility。
    重写ServiceAbility的生命周期方法,添加其他Ability请求与ServiceAbility交互时的处理方法。

  import rpc from "@ohos.rpc"
  
  class FirstServiceAbilityStub extends rpc.RemoteObject {
    constructor(des: any) {
      if (typeof des === 'string') {
        super(des)
      } else {
        return
      }
    }
  }
  
  export default {
    onStart() {
      console.info('ServiceAbility onStart')
    },
    onStop() {
      console.info('ServiceAbility onStop')
    },
    onCommand(want, startId) {
      console.info('ServiceAbility onCommand')
    },
    onConnect(want) {
      console.info('ServiceAbility onConnect' + want)
      return new FirstServiceAbilityStub('test')
    },
    onDisconnect(want) {
      console.info('ServiceAbility onDisconnect' + want)
    }
  }
  1. 注册ServiceAbility。
    ServiceAbility需要在应用配置文件config.json中进行注册,注册类型type需要设置为service。"visible"属性表示ServiceAbility是否可以被其他应用调用,true表示可以被其他应用调用,false表示不能被其他应用调用(仅应用内可以调用)。若ServiceAbility需要被其他应用调用,注册ServiceAbility时需要设置"visible"为true,同时需要设置支持关联启动。ServiceAbility的启动规则详见​​​组件启动规则​​章节。

     {
       "module": {
         "abilities": [
           {
             "name": ".ServiceAbility",
             "srcLanguage": "ets",
             "srcPath": "ServiceAbility",
             "icon": "$media:icon",
             "description": "hap sample empty service",
             "type": "service",
             "visible": true
           }
         ]
       }
     }

启动ServiceAbility

ServiceAbility的启动与其他Ability并无区别,应用开发者可以在PageAbility中通过featureAbility的startAbility接口拉起ServiceAbility,在ServiceAbility中通过particleAbility的startAbility接口拉起ServiceAbility。ServiceAbility的启动规则详见​​组件启动规则​​章节。

如下示例展示了在PageAbility中通过startAbility启动bundleName为"com.example.myapplication",abilityName为"ServiceAbility"的ServiceAbility的方法。启动FA模型的ServiceAbility时,需要在abilityName前拼接bundleName字符串。

import featureAbility from '@ohos.ability.featureAbility'

async function startServiceAbility() {
  try {
    console.info('Begin to start ability')
    let param = {
      want: {
        bundleName: "com.example.myapplication",
        abilityName: "com.example.myapplication.ServiceAbility"
      }
    }
    await featureAbility.startAbility(param)
    console.info(`Start ability succeed`)
  } catch (error) {
    console.error('Start ability failed with ' + error)
  }
}

执行上述代码后,Ability将通过startAbility() 方法来启动ServiceAbility。

  • 如果ServiceAbility尚未运行,则系统会先调用onStart()来初始化ServiceAbility,再回调Service的onCommand()方法来启动ServiceAbility。
  • 如果ServiceAbility正在运行,则系统会直接回调ServiceAbility的onCommand()方法来启动ServiceAbility。

连接ServiceAbility

如果ServiceAbility需要与PageAbility或其他应用的ServiceAbility进行交互,则须创建用于连接的Connection。ServiceAbility支持其他Ability通过connectAbility()方法与其进行连接。PageAbility的connectAbility方法定义在featureAbility中,ServiceAbility的connectAbility方法定义在particleAbility中。连接ServiceAbility的规则详见​​组件启动规则​​章节。在使用connectAbility()处理回调时,需要传入目标Service的Want与IAbilityConnection的实例。IAbilityConnection提供了以下方法供开发者实现。

表1 IAbilityConnection接口说明

接口名

描述

onConnect()

用于处理连接Service成功的回调。

onDisconnect()

用来处理Service异常死亡的回调。

onFailed()

用来处理连接Service失败的回调。

PageAbility创建连接本地ServiceAbility回调实例的代码以及连接本地ServiceAbility的示例代码如下:

import rpc from "@ohos.rpc"
import prompt from '@system.prompt'
import featureAbility from '@ohos.ability.featureAbility'

let option = {
  onConnect: function onConnectCallback(element, proxy) {
    console.info(`onConnectLocalService onConnectDone`)
    if (proxy === null) {
      prompt.showToast({
        message: "Connect service failed"
      })
      return
    }
    let data = rpc.MessageParcel.create()
    let reply = rpc.MessageParcel.create()
    let option = new rpc.MessageOption()
    data.writeInterfaceToken("connect.test.token")
    proxy.sendRequest(0, data, reply, option)
    prompt.showToast({
      message: "Connect service success"
    })
  },
  onDisconnect: function onDisconnectCallback(element) {
    console.info(`onConnectLocalService onDisconnectDone element:${element}`)
    prompt.showToast({
      message: "Disconnect service success"
    })
  },
  onFailed: function onFailedCallback(code) {
    console.info(`onConnectLocalService onFailed errCode:${code}`)
    prompt.showToast({
      message: "Connect local service onFailed"
    })
  }
}

let request = {
  bundleName: "com.example.myapplication",
  abilityName: "com.example.myapplication.ServiceAbility",
}
let connId = featureAbility.connectAbility(request, option)

同时,Service侧也需要在onConnect()时返回IRemoteObject,从而定义与Service进行通信的接口。onConnect()需要返回一个IRemoteObject对象。OpenHarmony提供了IRemoteObject的默认实现,开发者可以通过继承rpc.RemoteObject来创建自定义的实现类。

Service侧把自身的实例返回给调用侧的示例代码如下:

import rpc from "@ohos.rpc"

class FirstServiceAbilityStub extends rpc.RemoteObject {
  constructor(des: any) {
    if (typeof des === 'string') {
      super(des)
    } else {
      return
    }
  }

  onRemoteRequest(code: number, data: any, reply: any, option: any) {
    console.info(`onRemoteRequest called`)
    if (code === 1) {
      let string = data.readString()
      console.info(`string=${string}`)
      let result = Array.from(string).sort().join('')
      console.info(`result=${result}`)
      reply.writeString(result)
    } else {
      console.info(`unknown request code`)
    }
    return true
  }
}



文章转载自:​​https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/application-dev/application-models/connect-serviceability.md/​

已于2023-4-10 17:35:41修改
收藏
回复
举报
回复
    相关推荐