【HarmonyOS之旅】基于ArkTS开发(一) -> Ability开发一

目录

[1 -> FA模型综述](#1 -> FA模型综述)

[1.1 -> 整体架构](#1.1 -> 整体架构)

[1.2 -> 应用包结构](#1.2 -> 应用包结构)

[1.3 -> 生命周期](#1.3 -> 生命周期)

[1.4 -> 进程线程模型](#1.4 -> 进程线程模型)

[2 -> PageAbility开发](#2 -> PageAbility开发)

[2.1 -> 概述](#2.1 -> 概述)

[2.1.1 ->功能简介](#2.1.1 ->功能简介)

[2.1.2 -> PageAbility的生命周期](#2.1.2 -> PageAbility的生命周期)

[2.1.3 -> 启动模式](#2.1.3 -> 启动模式)

[2.2 -> featureAbility接口说明](#2.2 -> featureAbility接口说明)

[2.3 -> 启动本地PageAbility](#2.3 -> 启动本地PageAbility)

[2.4 -> 生命周期接口说明](#2.4 -> 生命周期接口说明)

[3 -> ServiceAbility开发](#3 -> ServiceAbility开发)

[3.1 -> 场景介绍](#3.1 -> 场景介绍)

[3.2 -> 接口说明](#3.2 -> 接口说明)

[3.3 -> 开发步骤](#3.3 -> 开发步骤)

[3.3.1 -> 创建Service](#3.3.1 -> 创建Service)

[3.3.2 -> 启动Service](#3.3.2 -> 启动Service)

[3.3.3 -> 停止Service](#3.3.3 -> 停止Service)

[3.3.4 -> 连接本地Service](#3.3.4 -> 连接本地Service)


1 -> FA模型综述

1.1 -> 整体架构

HarmonyOS用户程序的开发本质上就是开发Ability。HarmonyOS系统是通过对Ability调度,结合系统提供的一致性调度契约对Ability进行生命周期管理,从而实现对用户程序的调度。

Ability框架在API 8及更早版本使用FA模型。FA模型中Ability分为PageAbility、ServiceAbility、DataAbility、FormAbility几种类型。其中:

  • PageAbility是具备ArkUI实现的Ability,是用户具体可见并可以交互的Ability实例。
  • ServiceAbility也是Ability一种,但是没有UI,提供其他Ability调用自定义的服务,在后台运行。
  • DataAbility也是没有UI的Ability,提供其他Ability进行数据的增删查服务,在后台运行。
  • FormAbility是卡片Ability,是一种界面展示形式。

1.2 -> 应用包结构

1.3 -> 生命周期

在所有Ability中,PageAbility因为具有界面,也是应用的交互入口,因此生命周期更加复杂。

PageAbility生命周期回调如下图所示:

其他类型Ability的生命周期可参考PageAbility生命周期去除前后台切换以及onShow的部分进行理解。可以在 app.js/app.ets 中重写生命周期函数,在对应的生命周期函数内处理应用相应逻辑。目前app.js环境中仅支持onCreate和onDestroy回调,app.ets环境支持全量生命周期回调。

1.4 -> 进程线程模型

应用独享独立进程,Ability独享独立线程,应用进程在Ability第一次启动时创建,并为启动的Ability创建线程,应用启动后再启动应用内其他Ability,会为每一个Ability创建相应的线程。每个Ability绑定一个独立的JSRuntime实例,因此Ability之间是隔离的。

2 -> PageAbility开发

2.1 -> 概述

2.1.1 ->功能简介

PageAbility是具备ArkUI实现的Ability,是开发者具体可见并可以交互的Ability实例。开发者通过IDE创建Ability时,IDE会自动创建相关模板代码。PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过app.js/app.ets中各个回调函数实现。

2.1.2 -> PageAbility的生命周期

**PageAbility生命周期介绍(**Ability Life Cycle):

PageAbility生命周期是PageAbility被调度到INACTIVE、ACTIVE、BACKGROUND等各个状态的统称。

Ability生命周期状态说明:

  • UNINITIALIZED:未初始状态,为临时状态,PageAbility被创建后会由UNINITIALIZED状态进入INITIAL状态。

  • INITIAL:初始化状态,也表示停止状态,表示当前PageAbility未运行,PageAbility被启动后由INITIAL态进入ACTIVE状态。

  • INACTIVE:失去焦点状态,表示当前窗口已显示但是无焦点状态。

  • ACTIVE:前台激活状态,表示当前窗口已显示,并获取焦点。

  • BACKGROUND:后台状态,表示当前PageAbility退到后台,PageAbility在被销毁后由BACKGROUND状态进入INITIAL状态,或者重新被激活后由BACKGROUND状态进入ACTIVE状态。

PageAbility提供生命周期回调,开发者可以在app.js/app.ets中重写生命周期相关回调函数 。目前app.js环境中仅支持onCreate和onDestroy回调,app.ets环境支持全量生命周期回调。

2.1.3 -> 启动模式

ability支持单实例和多实例两种启动模式。

在config.json中通过launchType配置项,可以配置具体的启动模式。

|---------------|---------|----------------------------------------------------|
| 启动模式 | 描述 | 说明 |
| standard | 多实例 | 每次startAbility都会启动一个新的实例 |
| singleton | 单实例 | 系统中只存在唯一一个实例,startAbility时,如果已存在,则复用系统中的唯一一个实例 |

缺省情况下是singleton模式。

2.2 -> featureAbility接口说明

|---------------------------------------------------------|-----------------|
| 接口名 | 描述 |
| void startAbility(parameter: StartAbilityParameter) | 启动Ability |
| Context getContext(): | 获取应用Context |
| void terminateSelf() | 结束Ability |
| bool hasWindowFocus() | 是否获取焦点 |
[表1 featureAbility接口介绍]

2.3 -> 启动本地PageAbility

导入模块

java 复制代码
  import featureAbility from '@ohos.ability.featureAbility'

示例

java 复制代码
import featureAbility from '@ohos.ability.featureAbility'
featureAbility.startAbility({
    want:
    {
        action: "",
        entities: [""],
        type: "",
        options: {
            // Grant the permission to perform read operations on the URI.
            authReadUriPermission: true,
            // Grant the permission to perform write operations on the URI.
            authWriteUriPermission: true,
            // support forwarding the Want result to the ability.
            abilityForwardResult: true,
            // Enable ability continuation.
            abilityContinuation: true,
            // Specify that a component does not belong to ohos.
            notOhosComponent: true,
            // Specify that an ability is started.
            abilityFormEnabled: true,
            // Grant the permission for possible persisting on the URI.
            authPersistableUriPermission: true,
            // Grant the permission for possible persisting on the prefix URI.
            authPrefixUriPermission: true,
            // Support distributed scheduling system startup on multiple devices.
            abilitySliceMultiDevice: true,
            // A service ability is started regardless of whether the host application has been started.
            startForegroundAbility: true,
            // Install the specified ability if it is not installed.
            installOnDemand: true,
            // Return the result to the ability slice.
            abilitySliceForwardResult: true,
            // Install the specified ability with background mode if it is not installed.
            installWithBackgroundMode: true
        },
        deviceId: "",
        bundleName: "com.example.startability",
        abilityName: "com.example.startability.MainAbility",
        uri: ""
    },
});

want参数也可以使用parameters参数,使用key-value的方式输入。

示例

java 复制代码
import featureAbility from '@ohos.ability.featureAbility'
featureAbility.startAbility({
    want:
    {
        bundleName: "com.example.startability",
        uri: "",
        parameters: {
            abilityName: "com.example.startability.MainAbility"
        }
    },
});

2.4 -> 生命周期接口说明

|------------------|-----------------------------------------------------------------------|
| 接口名 | 描述 |
| onShow() | Ability由后台不可见状态切换到前台可见状态调用onShow方法,此时用户在屏幕可以看到该Ability。 |
| onHide() | Ability由前台切换到后台不可见状态时调用onHide方法,此时用户在屏幕看不到该Ability。 |
| onDestroy() | 应用退出,销毁Ability对象前调用onDestroy方法,开发者可以在该方法里做一些回收资源、清空缓存等应用退出前的准备工作。 |
| onCreate() | Ability第一次启动创建Ability时调用onCreate方法,开发者可以在该方法里做一些应用初始化工作。 |
| onInactive() | Ability失去焦点时调用onInactive方法,Ability在进入后台状态时会先失去焦点,再进入后台。 |
| onActive() | Ability切换到前台,并且已经获取焦点时调用onActive方法。 |
[表2 生命周期回调函数介绍]

示例

开需要重写app.js/app.ets中相关生命周期回调函数,IDE模板默认生成onCreate()和onDestroy()方法,其他方法需要自行实现。

java 复制代码
export default {
  onCreate() {
    console.info('Application onCreate')
  },
  onDestroy() {
    console.info('Application onDestroy')
  },
  onShow(){
    console.info('Application onShow')
  },
  onHide(){
    console.info('Application onHide')
  },
  onInactive(){
    console.info('Application onInactive')
  },
  onActive(){
    console.info('Application onActive')
  },
}

3 -> ServiceAbility开发

3.1 -> 场景介绍

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

3.2 -> 接口说明

|------------------|---------------------------------------------------------------------------|
| 接口名 | 描述 |
| onStart | 该方法在创建Service的时候调用,用于Service的初始化。在Service的整个生命周期只会调用一次,调用时传入的Want应为空。 |
| onCommand | 在Service创建完成之后调用,该方法在客户端每次启动该Service时都会调用,开发者可以在该方法中做一些调用统计、初始化类的操作。 |
| onConnect | 在Ability和Service连接时调用。 |
| onDisconnect | 在Ability与绑定的Service断开连接时调用。 |
| onStop | 在Service销毁时调用。Service应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。 |
[表3 Service中相关生命周期功能介绍]

3.3 -> 开发步骤

3.3.1 -> 创建Service

  1. Service也是一种Ability,Ability为Service提供了以下生命周期方法,开发者可以重写这些方法,来添加其他Ability请求与Service Ability交互时的处理方法。

创建Service的代码示例如下:

java 复制代码
export default {
    onStart() {
        console.log('ServiceAbility onStart');
    },
    onCommand(want, startId) {
        console.log('ServiceAbility onCommand');
    },
    onConnect(want) {
        console.log('ServiceAbility OnConnect');
        return new FirstServiceAbilityStub('test');
    },
    onDisconnect(want) {
        console.log('ServiceAbility OnDisConnect');
    },
    onStop() {
        console.log('ServiceAbility onStop');
    },
}
  1. 注册Service。

Service也需要在应用配置文件config.json中进行注册,注册类型type需要设置为service。

java 复制代码
 {
     "module": {
         "abilities": [         
             {    
                 "name": ".ServiceAbility",
                 "type": "service",
                 "visible": true
                 ...
             }
         ]
         ...
     }
     ...
 }

3.3.2 -> 启动Service

Ability为开发者提供了startAbility()方法来启动另外一个Ability。因为Service也是Ability的一种,开发者同样可以通过将Want传递给该方法来启动Service。

开发者可以通过构造包含bundleName与abilityName的Want对象来设置目标Service信息。参数的含义如下:

  • bundleName:表示包名称。
  • abilityName:表示待启动的Ability名称。
java 复制代码
import featureAbility from '@ohos.ability.featureAbility';
let promise = featureAbility.startAbility(
    {
        want:
        {
            bundleName: "com.jstest.service",
            abilityName: "com.jstest.service.ServiceAbility",
        },
    }
); 

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

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

3.3.3 -> 停止Service

Service一旦创建就会一直保持在后台运行,除非必须回收内存资源,否则系统不会停止或销毁Service。开发者可以在Service中通过terminateSelf()停止本Service。

3.3.4 -> 连接本地Service

如果Service需要与Page Ability或其他应用的Service Ability进行交互,则须创建用于连接的Connection。Service支持其他Ability通过connectAbility()方法与其进行连接。

在使用connectAbility()处理回调时,需要传入目标Service的Want与IAbilityConnection的实例。IAbilityConnection提供了以下方法供开发者实现:onConnect()是用来处理连接Service成功的回调,onDisconnect()是用来处理Service异常死亡的回调,onFailed()是用来处理连接Service失败的回调。

java 复制代码
import prompt from '@system.prompt'

var option = {
    onConnect: function onConnectCallback(element, proxy) {
        console.log(`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.log(`onConnectLocalService onDisconnectDone element:${element}`)
        prompt.showToast({
            message: "Disconnect service success"
        })
    },
    onFailed: function onFailedCallback(code) {
        console.log(`onConnectLocalService onFailed errCode:${code}`)
        prompt.showToast({
            message: "Connect local service onFailed"
        })
    }
}

连接本地Service的代码示例如下:

java 复制代码
import featureAbility from '@ohos.ability.featureAbility';
let connId = featureAbility.connectAbility(
    {
        bundleName: "com.jstest.service",
        abilityName: "com.jstest.service.ServiceAbility",
    },
    {
        onConnect: onConnectCallback,
        onDisconnect: onDisconnectCallback,
        onFailed: onFailedCallback,
    },
);

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

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

java 复制代码
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.log(printLog + ` onRemoteRequest called`)
    if (code === 1) {
        let string = data.readString()
        console.log(printLog + ` string=${string}`)
        let result = Array.from(string).sort().join('')
        console.log(printLog + ` result=${result}`)
        reply.writeString(result)
    } else {
        console.log(printLog + ` unknown request code`)
    }
    return true;
}

感谢各位大佬支持!!!

互三啦!!!

相关推荐
python算法(魔法师版)3 小时前
.NET 在鸿蒙系统上的适配现状
华为od·华为·华为云·.net·wpf·harmonyos
Anesthesia丶3 小时前
Vue3 + naive-ui + fastapi使用心得
vue.js·ui·fastapi
bestadc5 小时前
鸿蒙 UIAbility组件与UI的数据同步和窗口关闭
harmonyos
编程乐趣5 小时前
点下4个Winform UI开源控件库
ui·开源·mfc
枫叶丹45 小时前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十二)
华为·harmonyos·deveco studio·harmonyos next
ax一号街阿楠7 小时前
华为FAT AP配置 真机
网络·华为·智能路由器
吗喽对你问好7 小时前
华为5.7机考第一题充电桩问题Java代码实现
java·华为·排序
乱世刀疤9 小时前
深度 |国产操作系统“破茧而出”:鸿蒙电脑填补自主生态空白
华为·harmonyos
博睿谷IT99_14 小时前
华为HCIP-AI认证考试版本更新通知
人工智能·华为
连续讨伐15 小时前
ensp的华为小实验
华为