【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;
}

感谢各位大佬支持!!!

互三啦!!!

相关推荐
跳河轻生的鱼2 小时前
海思Linux(一)-Hi3516CV610的开发-ubuntu22_04环境创建
linux·单片机·学习·华为
weixin_464078074 小时前
开源Material Design WPF UI 控件库简单上手
ui·wpf
theMuseCatcher4 小时前
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
ui·typescript·vue3·vite·components
_可乐无糖5 小时前
深入理解 pytest_runtest_makereport:如何在 pytest 中自定义测试报告
android·ui·ios·自动化·pytest
轻口味6 小时前
【每日学点鸿蒙知识】跳转三方地图、getStringSync性能、键盘避让模式等
华为·harmonyos
儿歌八万首6 小时前
鸿蒙ArkUI实现部门树列表
华为·harmonyos·鸿蒙·arkui
IT 古月方源7 小时前
华为设备的VRP系统详解
运维·网络·网络协议·网络安全·华为
万少7 小时前
鸿蒙元服务实战-笑笑五子棋(5)
前端·harmonyos·canvas
塞尔维亚大汉8 小时前
移植案例与原理 - startup子系统之syspara_lite系统属性部件
操作系统·harmonyos
未来之窗软件服务8 小时前
软件架构设计——通用表单UI-提示确认框—未来之窗行业应用跨平台架构
前端·javascript·ui