一、鸿蒙 Ability 核心概念

1. Ability 定义与分类

Ability 是鸿蒙应用的最小功能单元,分为两类核心类型(FA/PA),对应不同应用场景:

类型

全称

核心作用

典型场景

PageAbility(FA)

Feature Ability

提供 UI 交互,承载页面展示

应用主页面、详情页等可视化界面

ServiceAbility(PA)

Particle Ability

提供后台服务,无 UI 界面

数据同步、音视频播放、网络请求等后台任务

2. 核心生命周期详解

(1)PageAbility 生命周期(UI 页面核心)

onCreate():页面创建时调用(初始化数据、绑定组件)

onDestroy():页面销毁时调用(释放资源、取消订阅)

onForeground():页面切换到前台时调用(刷新数据)

onBackground():页面切换到后台时调用(保存状态)

生命周期流程:onCreate() → onForeground() → 运行中 → onBackground() → onDestroy()

(2)ServiceAbility 生命周期(后台服务核心)

onStart():服务创建时调用(仅触发一次)

onCommand():接收其他组件调用请求时触发

onConnect():与其他组件建立连接时调用

onDisconnect():连接断开时调用

onStop():服务销毁时调用(释放后台资源)

3. FA 与 PA 的交互方式

PageAbility 调用 ServiceAbility:通过abilityManager.startAbility()启动服务,通过connectAbility()建立连接

ServiceAbility 向 PageAbility 通信:通过Intent传递数据,或使用事件总线(如Emitter)

二、服务卡片(Widget)开发全流程

服务卡片是鸿蒙特色功能,可在桌面展示核心信息,支持点击跳转 APP,开发需经历「配置→布局→数据绑定→交互实现」四步。

1. 核心配置文件

(1)应用配置文件(config.json)

需在module节点下声明卡片信息,指定卡片元数据路径:

// config.json

{

  "module": {

    "abilities": [

      {

        "name": ".WeatherAbility", // 关联的Ability名称

        "type": "page",

        "visible": true,

        "widgets": [

          {

            "name": "WeatherWidget", // 卡片名称(需与widget.json一致)

            "src": "./widgets/WeatherWidget", // 卡片资源路径

            "window": {

              "designWidth": 720, // 设计宽度(适配基准)

              "autoDesignWidth": true

            }

          }

        ]

      }

    ]

  }

}

(2)卡片元数据(widget.json)

在widgets/WeatherWidget目录下创建,定义卡片尺寸、更新策略:

// widgets/WeatherWidget/widget.json

{

  "name": "WeatherWidget",

  "description": "天气服务卡片",

  "author": "HarmonyOS Developer",

  "version": "1.0.0",

  "minAPIVersion": 9,

  "defaultDimension": "2*1", // 默认尺寸(宽2格×高1格)

  "supportedDimensions": ["2*1", "4*2"], // 支持的桌面尺寸

  "updateEnabled": true, // 允许数据刷新

  "updateDuration": 3600, // 默认刷新间隔(秒),最小30秒

  "defaultColorMode": "auto" // 自动适配深色/浅色模式

}

2. 卡片布局设计(widget.ets)

使用 ArkTS 组件编写卡片 UI,需遵循 “轻量布局” 原则(避免复杂嵌套):

// widgets/WeatherWidget/widget.ets

import router from '@ohos.router';

import { FlexAlign, ItemAlign } from '@ohos/ui';

@Entry

@Component

struct WeatherWidget {

  // 卡片数据(通过AppStorage实现全局共享)

  @Consume weatherData: { city: string; temp: number; condition: string };

  build() {

    Column({ space: 15, alignItems: ItemAlign.Center })

      .width('100%')

      .height('100%')

      .padding(20)

      .backgroundColor('#4a6cf7') {

      // 城市名称

      Text(this.weatherData.city)

        .fontSize(24)

        .fontWeight(FontWeight.Bold)

        .fontColor('#ffffff')

      // 温度与天气状况(水平排列)

      Row({ space: 20, alignItems: ItemAlign.Center }) {

        Text(`${this.weatherData.temp}℃`)

          .fontSize(36)

          .fontWeight(FontWeight.Bold)

          .fontColor('#ffffff')

        Text(this.weatherData.condition)

          .fontSize(20)

          .fontColor('#f0f8ff')

      }

      // 点击区域(跳转APP详情页)

      .onClick(() => {

        // 卡片点击跳转,指定目标页面

        router.pushUrl({

          url: 'pages/WeatherDetailPage'

        });

      })

    }

  }

}

3. 数据刷新实现

服务卡片数据刷新有两种核心方式,本文采用「定时刷新 + 主动更新」结合:

(1)全局数据共享(AppStorage)

在 Ability 中初始化数据并存储到 AppStorage,卡片通过@Consume接收:

// abilities/WeatherAbility.ets

import AppStorage from '@ohos.appstorage';

import { WeatherData } from '../model/WeatherModel';

@Entry

@Component

struct WeatherAbility {

  // 初始化天气数据并写入AppStorage

  private initWeatherData: WeatherData = {

    city: '北京',

    temp: 25,

    condition: '晴'

  };

  onCreate() {

    // 将数据存入全局AppStorage,供卡片消费

    AppStorage.setOrCreate('weatherData', this.initWeatherData);

    // 启动定时刷新(模拟实时更新)

    this.startWeatherRefresh();

  }

  // 定时刷新天气数据(每30分钟更新一次)

  startWeatherRefresh() {

    setInterval(() => {

      // 模拟接口请求获取新数据(实际开发替换为真实接口)

      const newTemp = this.initWeatherData.temp + Math.floor(Math.random() * 5) - 2;

      const newCondition = ['晴', '多云', '阴'][Math.floor(Math.random() * 3)];

      const updatedData = {

        ...this.initWeatherData,

        temp: newTemp,

        condition: newCondition

      };

      // 更新AppStorage,卡片自动同步

      AppStorage.set('weatherData', updatedData);

      this.initWeatherData = updatedData;

    }, 30 * 60 * 1000); // 30分钟刷新一次

  }

  build() {

    // 应用详情页布局(省略,可参考上一篇列表页实现)

    Column() {

      Text('天气详情页')

        .fontSize(32)

    }

    .width('100%')

    .height('100%')

  }

}

(2)数据模型定义(WeatherModel.ets)

// model/WeatherModel.ets

export interface WeatherData {

  city: string; // 城市名称

  temp: number; // 温度(℃)

  condition: string; // 天气状况(晴/多云/阴等)

}

4. 卡片点击事件与跳转

卡片中通过onClick绑定事件,使用router.pushUrl跳转至 APP 内页面

需确保目标页面已在main_pages.json中注册:

// main_pages.json

{

  "src": [

    "pages/WeatherDetailPage" // 天气详情页

  ]

}

三、实战:完整天气服务卡片代码整合

1. 项目目录结构

src/

├── abilities/

│   └── WeatherAbility.ets  // 主Ability(承载详情页+数据刷新)

├── pages/

│   └── WeatherDetailPage.ets  // 天气详情页

├── widgets/

│   └── WeatherWidget/

│       ├── widget.ets  // 卡片布局

│       └── widget.json  // 卡片元数据

├── model/

│   └── WeatherModel.ets  // 数据模型

├── config.json  // 应用配置

└── main_pages.json  // 页面路由配置

2. 关键功能说明

(1)数据同步机制

Ability 通过AppStorage存储天气数据,卡片通过@Consume实时接收更新

定时刷新通过setInterval模拟,实际开发可替换为鸿蒙BackgroundTaskManager实现后台稳定刷新

(2)尺寸适配

widget.json中supportedDimensions声明支持的桌面尺寸(21、42)

布局使用百分比宽度(width('100%'))和弹性布局,确保不同尺寸下显示正常

(3)生命周期联动

Ability 的onCreate初始化数据,onDestroy取消定时任务(避免内存泄漏):

// WeatherAbility.ets 补充onDestroy方法

onDestroy() {

  // 取消定时刷新任务

  clearInterval(this.refreshTimer);

}

四、常见问题与解决方案

1. 服务卡片不显示

检查config.json中widgets配置路径是否正确(需指向 widget.json 所在目录)

确保widget.json的minAPIVersion与项目编译版本一致

桌面添加卡片时选择对应尺寸(需在supportedDimensions中声明)

2. 数据不刷新

确认updateEnabled为true,且updateDuration不小于 30 秒

复杂数据更新需触发 AppStorage 引用变化,使用扩展运算符:AppStorage.set('weatherData', {...newData})

后台刷新需申请ohos.permission.KEEP_BACKGROUND_RUNNING权限

3. 卡片点击跳转失败

目标页面需在main_pages.json中注册

卡片中router.pushUrl的url路径需与配置一致

确保应用已安装(桌面卡片依赖应用存在)

加入班级,一起学习鸿蒙开发

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐