鸿蒙Ability Kit(程序框架服务)【Ability与ServiceExtensionAbility通信】

Ability与ServiceExtensionAbility通信

介绍

本示例展示通过[IDL的方式]和 [@ohos.rpc] 等接口实现了Ability与ServiceExtensionAbility之间的通信。

效果预览

使用说明

1.启动应用后,首页展示城市的天气信息,当前温度每隔5S会刷新一次。

工程目录

entry/src/main/ets/
|---Application
|---feature
|   |---HomeFeature.ets                  // 任务信息组件
|---MainAbility
|---Mock
|   |---RequestData.ts                   // 远程请求的数据
|   |---WeatherData.ts                   // 天气页面数据
|---model
|   |---FormDate.ts                      // 日期函数方法
|   |---Main.ts                          // 数据类
|---pages
|   |---home
|   |   |---BasicDataSource.ets          // 懒加载封装类
|   |   |---HomeContent.ets              // 内容组件
|   |   |---HoursWeather.ets             // 天气组件(小时)
|   |   |---IndexHeader.ets              // 首页头部组件
|   |   |---MultiDayWeather.ets          // 天气组件(天)
|   |---Home.ets                         // 首页
|---util
|   |---Logger.ts                        // 日志工具
|   |---Style.ts                         // 静态样式变量

具体实现

  • Ability与ServiceExtensionAbility通信的方法主要封装在idl_weather_service_proxy、idl_weather_service_stub、HomeFeature、ServiceExtAbility中。

  • 源码参考:[idl_weather_service_proxy.ts]

    /*

    • Copyright (c) 2022 Huawei Device Co., Ltd.

    • Licensed under the Apache License, Version 2.0 (the "License");

    • you may not use this file except in compliance with the License.

    • You may obtain a copy of the License at

    • http://www.apache.org/licenses/LICENSE-2.0
      
    • Unless required by applicable law or agreed to in writing, software

    • distributed under the License is distributed on an "AS IS" BASIS,

    • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

    • See the License for the specific language governing permissions and

    • limitations under the License.

    */

    import rpc from '@ohos.rpc'

    import { updateWeatherCallback } from './i_idl_weather_service'

    import IIdlWeatherService from './i_idl_weather_service'

    import Logger from '../../../util/Logger'

    export default class IdlWeatherServiceProxy implements IIdlWeatherService {

    constructor(proxy) {
    
      this.proxy = proxy
    
    }
    
    
    
    updateWeather(data: number, callback: updateWeatherCallback): void {
    
      let _option = new rpc.MessageOption(0)
    
      let _data = new rpc.MessageParcel()
    
      let _reply = new rpc.MessageParcel()
    
      _data.writeInt(data)
    
      this.proxy.sendRequest(IdlWeatherServiceProxy.COMMAND_UPDATE_WEATHER, _data, _reply, _option).then(function (result) {
    
        if (result.errCode === 0) {
    
          let _errCode = result.reply.readInt()
    
          if (_errCode != 0) {
    
            let _returnValue = undefined
    
            callback(_errCode, _returnValue)
    
            return
    
          }
    
          let _returnValue = result.reply.readInt()
    
          callback(_errCode, _returnValue)
    
        } else {
    
          Logger.error("sendRequest failed, errCode: " + result.errCode)
    
        }
    
      })
    
    }
    
    
    
    static readonly COMMAND_UPDATE_WEATHER = 1
    
    private proxy
    

    }

  • [idl_weather_service_stub.ts]

    /*

    • Copyright (c) 2022 Huawei Device Co., Ltd.

    • Licensed under the Apache License, Version 2.0 (the "License");

    • you may not use this file except in compliance with the License.

    • You may obtain a copy of the License at

    • http://www.apache.org/licenses/LICENSE-2.0
      
    • Unless required by applicable law or agreed to in writing, software

    • distributed under the License is distributed on an "AS IS" BASIS,

    • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

    • See the License for the specific language governing permissions and

    • limitations under the License.

    */

    import rpc from '@ohos.rpc'

    import { updateWeatherCallback } from './i_idl_weather_service'

    import IIdlWeatherService from './i_idl_weather_service'

    import Logger from '../../../util/Logger'

    export default class IdlWeatherServiceStub extends rpc.RemoteObject implements IIdlWeatherService {

    constructor(des: string) {
    
      super(des)
    
    }
    
    
    
    onRemoteRequest(code: number, data, reply, option): boolean {
    
      Logger.info("onRemoteRequest called, code = " + code)
    
      switch (code) {
    
        case IdlWeatherServiceStub.COMMAND_UPDATE_WEATHER: {
    
          let _data = data.readInt()
    
          this.updateWeather(_data, (errCode, returnValue) => {
    
            reply.writeInt(errCode)
    
            if (errCode == 0) {
    
              reply.writeInt(returnValue)
    
            }
    
          })
    
          return true
    
        }
    
        default: {
    
          Logger.error("invalid request code" + code)
    
          break
    
        }
    
      }
    
      return false
    
    }
    
    
    
    updateWeather(data: number, callback: updateWeatherCallback): void {
    
    }
    
    
    
    static readonly COMMAND_UPDATE_WEATHER = 1
    

    }

  • [HomeFeature]

    /*

    • Copyright (c) 2022 Huawei Device Co., Ltd.

    • Licensed under the Apache License, Version 2.0 (the "License");

    • you may not use this file except in compliance with the License.

    • You may obtain a copy of the License at

    • http://www.apache.org/licenses/LICENSE-2.0
      
    • Unless required by applicable law or agreed to in writing, software

    • distributed under the License is distributed on an "AS IS" BASIS,

    • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

    • See the License for the specific language governing permissions and

    • limitations under the License.

    */

    import Logger from '../util/Logger'

    import IdlWeatherServiceProxy from '../MainAbility/data/IIdlWeatherServiceTS/idl_weather_service_proxy'

    const BUNDLE_NAME = "com.example.abilityconnectserviceextension"

    const SERVICE_EXTENSION_ABILITY_NAME = "ServiceExtAbility"

    const ERROR_CODE = -1 // 失败

    const SUCCESS_CODE = 0 // 成功

    export default class HomeFeature {

    connection = -1 // 初始值
    
    remoteCallback = null
    
    context = null
    
    options = null
    
    
    
    constructor(context) {
    
      this.context = context
    
      this.options = {
    
        outObj: this,
    
        // 连接成功时回调
    
        onConnect: function (elementName, proxy) {
    
          Logger.info(`onConnect success`)
    
          // 接收来自服务返回的实例
    
          let weatherProxy = new IdlWeatherServiceProxy(proxy)
    
          weatherProxy.updateWeather(123, this.outObj.remoteCallback)
    
        },
    
        onDisconnect: function () {
    
          Logger.info(`onDisconnect`)
    
        },
    
        onFailed: function () {
    
          Logger.info(`onFailed`)
    
        }
    
      }
    
    }
    
    
    
    connectServiceExtAbility(callback) {
    
      Logger.info(`connectServiceExtAbility`)
    
      this.remoteCallback = callback
    
      let want = {
    
        bundleName: BUNDLE_NAME,
    
        abilityName: SERVICE_EXTENSION_ABILITY_NAME
    
      }
    
      this.connection = this.context.connectAbility(want, this.options)
    
      Logger.info(`connectServiceExtAbility result:${this.connection}`)
    
    }
    
    
    
    disconnectServiceExtAbility(callback) {
    
      Logger.info(`disconnectServiceExtAbility`)
    
      this.context.disconnectAbility(this.connection).then((data) => {
    
        Logger.info(`disconnectAbility success:${JSON.stringify(data)}`)
    
        callback(SUCCESS_CODE)
    
      }).catch((error) => {
    
        Logger.error(`disconnectAbility failed:${JSON.stringify(error)}`)
    
        callback(ERROR_CODE)
    
      })
    
    }
    

    }

  • [ServiceExtAbility]

    /*

    • Copyright (c) 2022 Huawei Device Co., Ltd.

    • Licensed under the Apache License, Version 2.0 (the "License");

    • you may not use this file except in compliance with the License.

    • You may obtain a copy of the License at

    • http://www.apache.org/licenses/LICENSE-2.0
      
    • Unless required by applicable law or agreed to in writing, software

    • distributed under the License is distributed on an "AS IS" BASIS,

    • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

    • See the License for the specific language governing permissions and

    • limitations under the License.

    */

    import ServiceExtension from '@ohos.app.ability.ServiceExtensionAbility'

    import IdlWeatherServiceStub from '../MainAbility/data/IIdlWeatherServiceTS/idl_weather_service_stub'

    import { updateWeatherCallback } from "../MainAbility/data/IIdlWeatherServiceTS/i_idl_weather_service"

    import { getUpdateTemperature } from '../mock/RequestData'

    import Logger from '../util/Logger'

    class WeatherServiceStub extends IdlWeatherServiceStub {

    constructor(des) {
    
      super(des)
    
    }
    
    
    
    updateWeather(data: number, callback: updateWeatherCallback): void {
    
      let temperature = getUpdateTemperature()
    
      callback(0, temperature)
    
      Logger.info(`testIntTransaction: temperature: ${temperature}`)
    
    }
    

    }

    export default class ServiceExtAbility extends ServiceExtension {

    onCreate(want) {
    
      Logger.info(`onCreate, want: ${want.abilityName}`)
    
    }
    
    
    
    onRequest(want, startId) {
    
      Logger.info(`onRequest, want: ${want.abilityName}`)
    
    }
    
    
    
    onConnect(want) {
    
      Logger.info(`onConnect , want: ${want.abilityName}`)
    
      return new WeatherServiceStub("weather service stub")
    
    }
    
    
    
    onDisconnect(want) {
    
      Logger.info(`onDisconnect, want: ${want.abilityName}`)
    
    }
    
    
    
    onDestroy() {
    
      Logger.info(`onDestroy`)
    
    }
    

    }

  • 建立服务器连接:通过HomeFeature中的this.context.connectAbility(want, this.options)方法来建立服务器连接;

  • 接收服务端实例并发送请求:连接成功时new IdlWeatherServiceProxy(proxy)来接收服务端实例,通过[@ohos.rpc] 接口来执行new rpc.MessageOption(0)、 new rpc.MessageParcel()、 new rpc.MessageParcel()获取 MessageParcel对象和请求的模式,调用idl_weather_service_proxy中的this.proxy.sendRequest()来发送请求;

  • 接收远程请求处理数据:在idl_weather_service_stub中接收远程请求并通过ServiceExtAbility中的updateWeather()函数来处理数据进行返回;

  • 获取数据:最后将获得的数据渲染到页面中去;

  • 断开连接:可以通过HomeFeature中的this.context.disconnectAbility(this.connection)方法来断开服务器连接,这里的this.connection是建立连接之后的返回值。

相关推荐
碎像9 分钟前
鸿蒙 HarmonyOS Next 路由 不废话 全干货
开发语言·华为·harmonyos
肖哥弹架构2 小时前
策略模式(Strategy Pattern):电商平台的优惠券系统实战案例分析
前端·后端·程序员
通信学生一枚3 小时前
LMT加仿真,十一届大唐杯全国总决赛
大学生·通信·比赛·大唐杯
肖哥弹架构3 小时前
组合模式(Composite Pattern): 在线教育平台课程管理实战案例分析
前端·后端·程序员
chenhua10086117 小时前
鸿蒙应用更新跳转到应用市场
华为·harmonyos
andylauren11 小时前
Hi3861 OpenHarmony嵌入式应用入门--UDP Server
udp·openharmony
txwtech20 小时前
58.鸿蒙系统app(HarmonyOS)(ArkUI)更改应用程序图标
鸿蒙系统
老肖相当外语大佬1 天前
关于领域驱动设计,大家都理解错了
程序员·ddd·领域驱动设计·软件设计
dadalaohua1 天前
【学习笔记】Fréchet距离的 C 语言实现
c语言·人工智能·笔记·学习·程序员
热爱可抵岁月漫长_Tiffany1 天前
2. DOM 事件基础 - 注册事件、tab 栏切换(1)之事件监听、随机点名案例、事件类型及实例
前端·javascript·程序员