OpenHarmony应用开发-ExtensionAbility组件

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

版本:v3.2 Beta5

ExtensionAbility组件概述

ExtensionAbility组件是基于特定场景(例如服务卡片、输入法等)提供的应用组件,以便满足更多的使用场景。

每一个具体场景对应一个​​ExtensionAbilityType​​,各类型的ExtensionAbility组件均由相应的系统服务统一管理,例如InputMethodExtensionAbility组件由输入法管理服务统一管理。当前支持的ExtensionAbility类型有:

说明:

  1. OpenHarmony不支持三方应用实现ServiceExtensionAbility、DataShareExtensionAbility、StaticSubscriberExtensionAbility和WindowExtensionAbility。
  2. 如果三方开发者想要实现后台处理相关事务的功能,无法使用ServiceExtensionAbility,可以使用后台任务,具体请参见​​后台任务​​。
  3. 三方应用只能使用当前系统已定义的上述类型的ExtensionAbility。

使用指定类型的ExtensionAbility组件

所有类型的ExtensionAbility组件均不能被应用直接启动,而是由相应的系统管理服务拉起,以确保其生命周期受系统管控,使用时拉起,使用完销毁。ExtensionAbility组件的调用方无需关心目标ExtensionAbility组件的生命周期。

以​​InputMethodExtensionAbility​​​组件为例进行说明,如下图所示,调用方应用发起对InputMethodExtensionAbility组件的调用,此时将先调用输入法管理服务,由输入法管理服务拉起​​InputMethodExtensionAbility​​组件,返回给调用方,同时开始管理其生命周期。

图1 使用InputMethodExtensionAbility组件

OpenHarmony应用开发-ExtensionAbility组件-鸿蒙开发者社区

实现指定类型的ExtensionAbility组件

以实现卡片​​FormExtensionAbility​​​为例进行说明。卡片框架提供了​​FormExtensionAbility​​​基类,开发者通过派生此基类(如MyFormExtensionAbility),实现回调(如创建卡片的onCreate()回调、更新卡片的onUpdateForm()回调等)来实现具体卡片功能,具体见开发指导见​​服务卡片FormExtensionAbility​​。

卡片FormExtensionAbility实现方不用关心使用方何时去请求添加、删除卡片,FormExtensionAbility实例及其所在的ExtensionAbility进程的整个生命周期,都是由卡片管理系统服务FormManagerService进行调度管理。

OpenHarmony应用开发-ExtensionAbility组件-鸿蒙开发者社区

说明: 同一应用内的所有同类型的ExtensionAbility运行在同一独立进程(除ServiceExtensionAbility、DataShareExtensionAbility外),跟UIAbility组件不在同一进程,Stage模型的进程模型请参见​​进程模型​​。

例如一个应用有1个UIAbility组件、1个ServiceExtensionAbility、1个DataShareExtensionAbility、2个FormExtensionAbility、1个ImeExtensionAbility。则该应用在运行时,有三个进程:

  • UIAbility、ServiceExtensionAbility、DataShareExtensionAbility运行在同一个进程。
  • FormExtensionAbility运行在一个独立进程。
  • ImeExtensionAbility运行在一个独立进程。

ServiceExtensionAbility

​ServiceExtensionAbility​​是SERVICE类型的ExtensionAbility组件,提供后台服务相关扩展能力。

​ServiceExtensionAbility​​​可以被其他组件启动或连接,并根据调用者的请求信息在后台处理相关事务。​​ServiceExtensionAbility​​​支持以启动和连接两种形式运行,系统应用可以调用​​startServiceExtensionAbility()​​​方法启动后台服务,也可以调用​​connectServiceExtensionAbility()​​​方法连接后台服务,而三方应用只能调用​​connectServiceExtensionAbility()​​方法连接后台服务。启动和连接后台服务的差别:

  • 启动:AbilityA启动ServiceB,启动后AbilityA和ServiceB为弱关联,AbilityA退出后,ServiceB可以继续存在。
  • 连接:AbilityA绑定ServiceB,绑定后AbilityA和ServiceB为强关联,AbilityA退出后,ServiceB也一起退出。

每个类型的ExtensionAbility都有自己的Context,ServiceExtensionAbility通过​​ServiceExtensionContext​​提供相关能力。本文描述中称被启动的ServiceExtensionAbility为服务端,称启动ServiceExtensionAbility的组件为客户端。

本章节将从如下场景来介绍ServiceExtensionAbility的基本使用。

说明:

  1. OpenHarmony当前不支持三方应用实现ServiceExtensionAbility。如果三方开发者想要实现后台处理相关事务的功能,可以使用后台任务,具体请参见​​后台任务​​。
  2. 三方应用的UIAbility组件可以通过Context连接系统提供的ServiceExtensionAbility。
  3. 三方应用需要在前台获焦的情况下才能连接系统提供的ServiceExtensionAbility。

实现一个后台服务(仅对系统应用开放)

​ServiceExtensionAbility​​提供了onCreate()、onRequest()、onConnect()、onDisconnect()和onDestory()生命周期回调,根据需要重写对应的回调方法。下图展示了ServiceExtensionAbility的生命周期。

图1 ServiceExtensionAbility生命周期

OpenHarmony应用开发-ExtensionAbility组件-鸿蒙开发者社区

  • onCreate服务被首次创建时触发该回调,开发者可以在此进行一些初始化的操作,例如注册公共事件监听等。

说明:

如果服务已创建,再次启动该ServiceExtensionAbility不会触发onCreate()回调。

  • onRequest当另一个组件调用startServiceExtensionAbility()方法启动该服务组件时,触发该回调。执行此方法后,服务会启动并在后台运行。
  • onConnect当另一个组件调用connectServiceExtensionAbility()方法与该服务连接时,触发该回调。开发者在此方法中,返回一个远端代理对象(IRemoteObject),客户端拿到这个对象后可以通过这个对象与服务端进行RPC通信。
  • onDisconnect其他组件调用disconnectServiceExtensionAbility()方法时,如果没有任何其他组件连接该服务,触发该回调。
  • onDestroy当不再使用服务且准备将其销毁该实例时,触发该回调。开发者可以在该回调中清理资源,如注销监听等。

开发步骤

开发者在实现一个后台服务时,需要在DevEco Studio工程中手动新建一个ServiceExtensionAbility,具体步骤如下。

  1. 在工程Module对应的ets目录下,右键选择“New > Directory”,新建一个目录并命名为serviceextability。
  2. 在serviceextability目录,右键选择“New > ts File”,新建一个TS文件并命名为ServiceExtAbility.ts。
  3. 打开ServiceExtAbility.ts文件,导入​​RPC通信模块​​,重载onRemoteMessageRequest()方法,接收客户端传递过来的消息,并将处理的结果返回给客户端。REQUEST_VALUE用于校验客户端发送的服务请求码。

import rpc from '@ohos.rpc';

const REQUEST_CODE = 99;

class StubTest extends rpc.RemoteObject {
  constructor(des) {
    super(des);
  }
  
  // 接收客户端传递过来的消息处理,以及将处理的结果返回给客户端
  onRemoteMessageRequest(code, data, reply, option) {
    if (code === REQUEST_CODE) {
      // 接收客户端传递过来的数据
      // 客户端使用多次调用data.writeInt()写入多个数据时,服务端可以通过多次调用data.readInt()方法接收对应的数据
      let optFir = data.readInt();
      let optSec = data.readInt();
      // 服务端将数据的处理结果返回给客户端
      // 示例中为接收了两个数据,并将两个数据的求和返回给客户端
      reply.writeInt(optFir + optSec);
    }
    return true;
  }

  // 以同步或异步方式向客户端发送消息
  sendRequest(code, data, reply, options) {
    return null;
  }
}
  1. 在ServiceExtAbility.ts文件中,增加导入ServiceExtensionAbility的依赖包,自定义类继承ServiceExtensionAbility并加上需要的生命周期回调。

import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
import rpc from '@ohos.rpc';

const TAG: string = "[Example].[Entry].[ServiceExtAbility]";
const REQUEST_CODE = 99;

class StubTest extends rpc.RemoteObject {
  // ...
}

export default class ServiceExtAbility extends ServiceExtensionAbility {
  onCreate(want) {
    console.info(TAG, `onCreate, want: ${want.abilityName}`);
  }

  onRequest(want, startId) {
    console.info(TAG, `onRequest, want: ${want.abilityName}`);
  }

  onConnect(want) {
    console.info(TAG, `onConnect, want: ${want.abilityName}`);
    return new StubTest("test");
  }

  onDisconnect(want) {
    console.info(TAG, `onDisconnect, want: ${want.abilityName}`);
  }

  onDestroy() {
    console.info(TAG, `onDestroy`);
  }
}
  1. 在工程Module对应的​​module.json5配置文件​​中注册ServiceExtensionAbility,type标签需要设置为“service”,srcEntrance标签表示当前ExtensionAbility组件所对应的代码路径。

{
  "module": {
    // ...
    "extensionAbilities": [
      {
        "name": "ServiceExtAbility",
        "icon": "$media:icon",
        "description": "service",
        "type": "service",
        "visible": true,
        "srcEntrance": "./ets/serviceextability/ServiceExtAbility.ts"
      }
    ]
  }
}

启动一个后台服务(仅对系统应用开放)

系统应用通过​​startServiceExtensionAbility()​​​方法启动一个后台服务,服务的​​onRequest()​​​回调就会被调用,并在该回调方法中接收到调用者传递过来的want对象。后台服务启动后,其生命周期独立于客户端,即使客户端已经销毁,该后台服务仍可继续运行。因此,后台服务需要在其工作完成时通过调用ServiceExtensionContext的​​terminateSelf()​​​来自行停止,或者由另一个组件调用​​stopServiceExtensionAbility()​​来将其停止。

说明: ServiceExtensionContext的​​startServiceExtensionAbility()​​​、​​stopServiceExtensionAbility()​​​和​​terminateSelf()​​为系统接口,三方应用不支持调用。

  1. 在系统应用中启动一个新的ServiceExtensionAbility。示例中的context的获取方式参见​​获取UIAbility的Context属性​​。

let want = {
    "deviceId": "",
    "bundleName": "com.example.myapplication",
    "abilityName": "ServiceExtAbility"
};
this.context.startServiceExtensionAbility(want).then(() => {
    console.info('startServiceExtensionAbility success');
}).catch((error) => {
    console.info('startServiceExtensionAbility failed');
})
  1. 在系统应用中停止一个已启动的ServiceExtensionAbility。

let want = {
    "deviceId": "",
    "bundleName": "com.example.myapplication",
    "abilityName": "ServiceExtAbility"
};
this.context.stopServiceExtensionAbility(want).then(() => {
    console.info('stopServiceExtensionAbility success');
}).catch((error) => {
    console.info('stopServiceExtensionAbility failed');
})
  1. 已启动的ServiceExtensionAbility停止自身。

// this是当前ServiceExtensionAbility
this.context.terminateSelf().then(() => {
    console.info('terminateSelf success');
}).catch((error) => {
    console.info('terminateSelf failed');
})

说明: 后台服务可以在后台长期运行,为了避免资源浪费,需要对后台服务的生命周期进行管理。即一个后台服务完成了请求方的任务,需要及时销毁。销毁已启动的后台服务有两种方式:

调用​​terminateSelf()​​​或​​stopServiceExtensionAbility()​​方法之后,系统将销毁后台服务。

连接一个后台服务

系统应用或者三方应用可以通过​​connectServiceExtensionAbility()​​​连接一个服务(在Want对象中指定启动的目标服务),服务的​​onConnect()​​就会被调用,并在该回调方法中接收到调用者传递过来的Want对象,从而建立长连接。

ServiceExtensionAbility服务组件在​​onConnect()​​​中返回IRemoteObject对象,开发者通过该IRemoteObject定义通信接口,用于客户端与服务端进行RPC交互。多个客户端可以同时连接到同一个后台服务,客户端完成与服务的交互后,客户端需要通过调用​​disconnectServiceExtensionAbility()​​来断开连接。如果所有连接到某个后台服务的客户端均已断开连接,则系统会销毁该服务。

import rpc from '@ohos.rpc';

const REQUEST_CODE = 99;
let want = {
    "deviceId": "",
    "bundleName": "com.example.myapplication",
    "abilityName": "ServiceExtAbility"
};
let options = {
    onConnect(elementName, remote) {
        console.info('onConnect callback');
        if (remote === null) {
            console.info(`onConnect remote is null`);
            return;
        }
        let option = new rpc.MessageOption();
        let data = new rpc.MessageParcel();
        let reply = new rpc.MessageParcel();
        data.writeInt(100);
        data.writeInt(200);

        // @param code 表示客户端发送的服务请求代码。
        // @param data 表示客户端发送的{@link MessageParcel}对象。
        // @param reply 表示远程服务发送的响应消息对象。
        // @param options 指示操作是同步的还是异步的。
        // 
        // @return 如果操作成功返回{@code true}; 否则返回 {@code false}。
        remote.sendRequest(REQUEST_CODE, data, reply, option).then((ret) => {
            let msg = reply.readInt();
            console.info(`sendRequest ret:${ret} msg:${msg}`);
        }).catch((error) => {
            console.info('sendRequest failed');
        });
    },
    onDisconnect(elementName) {
        console.info('onDisconnect callback')
    },
    onFailed(code) {
        console.info('onFailed callback')
    }
}
// 建立连接后返回的Id需要保存下来,在解绑服务时需要作为参数传入
let connectionId = this.context.connectServiceExtensionAbility(want, options);
  • 使用disconnectServiceExtensionAbility()断开与后台服务的连接。

let connectionId = 1 // 在通过connectServiceExtensionAbility绑定服务时返回的Id
this.context.disconnectServiceExtensionAbility(connectionId).then((data) => {
    console.info('disconnectServiceExtensionAbility success');
}).catch((error) => {
    console.error('disconnectServiceExtensionAbility failed');
})

相关示例

针对ServiceExtensionAbility开发,有以下相关示例可供参考:

DataShareExtensionAbility(仅对系统应用开放)

DataShareExtensionAbility提供了数据分享的能力,系统应用可以实现一个DataShareExtensionAbility,也可以访问系统中已有的DataShareExtensionAbility,针对三方应用仅开放访问系统中已有DataShareExtensionAbility的能力,详细介绍请参见​​数据共享开发指导​​。

EnterpriseAdminExtensionAbility开发指南

EnterpriseAdminExtensionAbility简介

企业设备管理扩展能力,是MDM应用必备组件。当开发者为企业开发MDM(Mobile Device Management)应用时,需继承EnterpriseAdminExtensionAbility,在EnterpriseAdminExtensionAbility实例中实现MDM业务逻辑,EnterpriseAdminExtensionAbility实现了系统管理状态变化通知功能,并定义了管理应用激活、去激活、应用安装、卸载事件等回调接口。

约束与限制

  • 功能限制
    仅支持设备管理员应用使用。

场景:监听设备管理器激活、去激活、应用安装、卸载事件

概述

onAdminEnabled:由企业管理员或者员工部署MDM应用,激活设备管理器,系统通知MDM应用已激活DeviceAdmin权限。MDM应用可在onAdminEnabled回调函数中进行初始化策略设置。

onAdminDisabled:由系统或者员工去激活设备管理器,通知去激活DeviceAdmin权限,应用可以通知企业管理员设备已脱管。

onBundleAdded: 企业应用管理场景下,企业管理员订阅应用安装卸载事件,端侧应用安装和卸载事件通知MDM应用,MDM应用可以在回调函数中进行事件上报,通知企业管理员。

onBundleRemoved: 企业应用管理场景下,企业管理员取消订阅应用安装卸载事件。

接口说明

类名

接口名称

描述

EnterpriseAdminExtensionAbility

onAdminDisabled(): void

设备管理器应用去激活回调方法

EnterpriseAdminExtensionAbility

onBundleAdded(bundleName: string): void

应用安装回调方法

EnterpriseAdminExtensionAbility

onAdminEnabled(): void

设备管理器应用激活回调方法

EnterpriseAdminExtensionAbility

onBundleRemoved(bundleName: string): void

应用卸载回调方法

开发步骤

开发者在实现EnterpriseAdminExtensionAbility的时候,需先激活设备管理员应用,并在设备管理员应用的代码目录下新建ExtensionAbility,具体步骤如下。

  1. 在工程Module对应的ets目录下,右键选择“New > Directory”,新建一个目录并命名为EnterpriseExtAbility。
  2. 在EnterpriseExtAbility目录,右键选择“New > TypeScript File”,新建一个TypeScript文件并命名为EnterpriseExtAbility.ts。
  3. 打开EnterpriseExtAbility.ts文件,导入EnterpriseAdminExtensionAbility模块,自定义类继承EnterpriseAdminExtensionAbility并加上需要的应用通知回调方法,如onAdminEnabled()、onAdminDisabled()等回调方法。当设备管理员应用被激活或者去激活时,则可以在对应回调方法中接受系统发送通知。

import EnterpriseAdminExtensionAbility from '@ohos.enterprise.EnterpriseAdminExtensionAbility';

export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbility {

    onAdminEnabled() {
        console.info("onAdminEnabled");
    }

    onAdminDisabled() {
        console.info("onAdminDisabled");
    }
    
    onBundleAdded(bundleName: string) {
        console.info("EnterpriseAdminAbility onBundleAdded bundleName:" + bundleName)
    }

    onBundleRemoved(bundleName: string) {
        console.info("EnterpriseAdminAbility onBundleRemoved bundleName" + bundleName)
    }
};

​ 4.在工程Module对应的​​module.json5​​配置文件中注册ServiceExtensionAbility,type标签需要设置为“enterpriseAdmin”,srcEntrance标签表示当前ExtensionAbility组件所对应的代码路径。

"extensionAbilities": [
      {
        "name": "ohos.samples.enterprise_admin_ext_ability",
        "type": "enterpriseAdmin",
        "visible": true,
        "srcEntrance": "./ets/enterpriseextability/EnterpriseAdminAbility.ts"
      }
    ]

使用示例

通过@ohos.enterprise.adminManager模块中的subscribeManagedEvent接口和unsubscribeManagedEvent接口进行企业设备管理事件的订阅,订阅应用安装、卸载事件。当订阅成功后,端侧应用安装和卸载事件通知MDM应用,MDM应用可以在回调函数中进行事件上报,通知企业管理员。

  @State managedEvents: Array<adminManager.ManagedEvent> = [0,1]
  @State subscribeManagedEventMsg: string = ""
  @State unsubscribeManagedEventMsg: string = ""

  async subscribeManagedEventCallback() {
    await adminManager.subscribeManagedEvent(this.admin,
      [adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_ADDED,
      adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_REMOVED], (error) => {
        if (error) {
          this.subscribeManagedEventMsg = 'subscribeManagedEvent Callback::errorCode: ' + error.code + ' errorMessage: ' + error.message
        } else {
          this.subscribeManagedEventMsg = 'subscribeManagedEvent Callback::success'
        }
      })
  }

  async unsubscribeManagedEventPromise() {
    await adminManager.unsubscribeManagedEvent(this.admin,
      [adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_ADDED,
      adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_REMOVED]).then(() => {
      this.unsubscribeManagedEventMsg = 'unsubscribeManagedEvent Promise::success'
    }).catch((error) => {
      this.unsubscribeManagedEventMsg = 'unsubscribeManagedEvent Promise::errorCode: ' + error.code + ' errorMessage: ' + error.message
    })
  }

相关实例

针对EnterpriseAdminExtensionAbility开发,有以下相关示例可供参考:

​EnterpriseAdminExtensionAbility:EnterpriseAdminExtensionAbility的创建与使用(ArkTS) (API9)​




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

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