Stage模型进阶:多Ability与Window管理(2026版)

4 阅读5分钟

Stage模型进阶:多Ability与Window管理(2026版)

基于 HarmonyOS 6.1 | 纯血鸿蒙 | 2025-2026 新体系

目录

  1. 多Ability通信
  2. Ability 启动模式
  3. 数据持久化与Ability间传递
  4. 窗口高级管理
  5. ExtensionAbility 开发
  6. 实战案例:音乐播放服务

多Ability通信

启动Ability并传递数据

// pages/Index.ets
import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'

@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext

  startSecondAbility() {
    const want: Want = {
      bundleName: 'com.example.myapp',
      abilityName: 'SecondAbility',
      parameters: {
        key1: 'Hello from Index',
        key2: 12345,
        key3: true
      }
    }

    this.context.startAbility(want)
      .then(() => {
        console.log('启动SecondAbility成功')
      })
      .catch((err: BusinessError) => {
        console.error('启动失败:' + JSON.stringify(err))
      })
  }

  build() {
    Column() {
      Button('启动SecondAbility')
        .onClick(() => this.startSecondAbility())
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

接收Ability数据

// entryability/SecondAbility.ets
import UIAbility from '@ohos.app.ability.UIAbility'
import Want from '@ohos.app.ability.Want'
import AbilityConstant from '@ohos.app.ability.AbilityConstant'

export default class SecondAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
    console.log('接收到的数据:')
    console.log('key1:' + want.parameters?.key1)
    console.log('key2:' + want.parameters?.key2)
    console.log('key3:' + want.parameters?.key3)
  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {
    // Ability已存在时,接收新的Want数据
    console.log('onNewWant:' + JSON.stringify(want.parameters))
  }
}

使用EventHub进行Ability内通信

// entryability/EntryAbility.ets
export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
    // 注册事件监听
    this.context.eventHub.on('event_test', (data) => {
      console.log('收到事件:' + JSON.stringify(data))
    })
  }
}
// pages/Index.ets
@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext

  sendEvent() {
    // 发送事件(Ability内通信)
    this.context.eventHub.emit('event_test', { msg: 'Hello EventHub' })
  }

  build() {
    Column() {
      Button('发送事件')
        .onClick(() => this.sendEvent())
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

Ability 启动模式

启动模式配置(module.json5)

{
  "module": {
    "abilities": [
      {
        "name": "EntryAbility",
        "launchType": "singleton",  // 单实例(默认)
        // "launchType": "multiton",   // 多实例
        // "launchType": "specified",   // 指定实例(需配合onNewWant)
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        // ...其他配置
      }
    ]
  }
}

启动模式对比

模式说明使用场景
singleton单实例(默认)主页面、大多数场景
multiton多实例需要同时打开多个相同Ability
specified指定实例根据参数决定复用哪个实例

specified 模式示例

// entryability/EntryAbility.ets
export default class EntryAbility extends UIAbility {
  // specified模式下,指定实例Key
  onAcceptWant(want: Want): string {
    // 根据want参数返回实例Key
    if (want.parameters?.documentId) {
      return `doc_${want.parameters.documentId}`
    }
    return 'default'
  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {
    console.log('指定实例onNewWant:' + JSON.stringify(want.parameters))
  }
}

数据持久化与Ability间传递

使用AppStorage(全局持久化)

// AppStorage 设置
AppStorage.SetOrCreate('globalData', { count: 0, name: 'HarmonyOS' })

// Ability1 读取/修改
@Entry
@Component
struct Page1 {
  @StorageLink('globalData') globalData: Object = {}

  build() {
    Column() {
      Text(`count:${(this.globalData as Record<string, number>)['count']}`)
      
      Button('count+1')
        .onClick(() => {
          (this.globalData as Record<string, number>)['count'] += 1
          // 自动同步到所有监听该key的页面
        })
    }
  }
}

使用Preferences(轻量级存储)

import dataPreferences from '@ohos.data.preferences'

@Entry
@Component
struct PreferencesDemo {
  private context = getContext(this) as common.UIAbilityContext
  private preferences: dataPreferences.Preferences | null = null

  async aboutToAppear() {
    try {
      // 获取Preferences实例
      this.preferences = await dataPreferences.getPreferences(this.context, 'myApp')

      // 读取数据
      const value = await this.preferences.get('username', 'default')
      console.log('username:' + value)

    } catch (err) {
      console.error('Preferences操作失败:' + JSON.stringify(err))
    }
  }

  async saveData() {
    try {
      // 写入数据
      await this.preferences?.put('username', '张三')
      await this.preferences?.put('age', 25)

      // 刷盘
      await this.preferences?.flush()
      console.log('保存成功')
    } catch (err) {
      console.error('保存失败:' + JSON.stringify(err))
    }
  }

  build() {
    Column() {
      Button('保存数据')
        .onClick(() => this.saveData())
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

使用关系型数据库(RDB)

import relationalStore from '@ohos.data.relationalStore'

@Entry
@Component
struct RDBDemo {
  private context = getContext(this) as common.UIAbilityContext
  private rdbStore: relationalStore.RdbStore | null = null

  async aboutToAppear() {
    try {
      // 配置RDB
      const config: relationalStore.StoreConfig = {
        name: 'MyApp.db',
        securityLevel: relationalStore.SecurityLevel.S1
      }

      // 创建/获取RDB
      this.rdbStore = await relationalStore.getRdbStore(this.context, config)

      // 创建表
      await this.rdbStore.executeSql(
        'CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)'
      )

      console.log('RDB初始化成功')
    } catch (err) {
      console.error('RDB初始化失败:' + JSON.stringify(err))
    }
  }

  async insertData() {
    try {
      const valueBucket: relationalStore.ValuesBucket = {
        'id': 1,
        'name': '张三',
        'age': 25
      }
      await this.rdbStore?.insert('user', valueBucket)
      console.log('插入成功')
    } catch (err) {
      console.error('插入失败:' + JSON.stringify(err))
    }
  }

  build() {
    Column() {
      Button('插入数据')
        .onClick(() => this.insertData())
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

窗口高级管理

窗口类型(HarmonyOS 6.1)

import window from '@ohos.window'

// 窗口类型
const windowType = window.WindowType

// TYPE_APP:应用主窗口
// TYPE_SUB_WINDOW:应用子窗口
// TYPE_DIALOG:对话框窗口
// TYPE_SYSTEM_ALERT:系统警示窗口(需权限)

设置窗口属性

@Entry
@Component
struct WindowDemo {
  private context = getContext(this) as common.UIAbilityContext
  private mainWindow: window.Window | null = null

  async aboutToAppear() {
    try {
      // 获取主窗口
      this.mainWindow = await window.getLastWindow(this.context)

      // 设置全屏
      await this.mainWindow.setWindowLayoutFullScreen(true)

      // 设置状态栏
      await this.mainWindow.setWindowSystemBarProperties({
        statusBarColor: '#ffffff',
        statusBarContentColor: '#000000',
        navigationBarColor: '#ffffff',
        navigationBarContentColor: '#000000'
      })

      // 设置窗口亮度
      await this.mainWindow.setWindowBrightness(0.8)

      // 设置窗口透明度
      await this.mainWindow.setWindowAlpha(1.0)

      // 设置窗口焦点模式
      await this.mainWindow.setWindowFocusable(true)

      // 设置触摸穿透
      await this.mainWindow.setWindowTouchable(true)

    } catch (err) {
      console.error('窗口设置失败:' + JSON.stringify(err))
    }
  }

  build() {
    Column() {
      Text('窗口管理示例')
        .fontSize(20)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

避免窗口内容被键盘遮挡(2026新增)

// entryability/EntryAbility.ets
onWindowStageCreate(windowStage: window.WindowStage) {
  windowStage.loadContent('pages/Index')

  const mainWindow = windowStage.getMainWindowSync()

  // 设置键盘避让模式(2025-2026新增API)
  mainWindow.setKeyboardAvoidMode(window.KeyboardAvoidMode.RESIZE)  // 调整窗口大小
  // 或
  mainWindow.setKeyboardAvoidMode(window.KeyboardAvoidMode.RESIZE | window.KeyboardAvoidMode.PAN)  // 调整+平移
}

ExtensionAbility 开发

创建FormExtensionAbility(卡片扩展)

// entryformability/EntryFormAbility.ets
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'
import formBindingData from '@ohos.app.form.formBindingData'

export default class EntryFormAbility extends FormExtensionAbility {
  onAddForm(want: Want) {
    console.log('卡片添加:' + JSON.stringify(want))

    // 返回卡片数据
    const formData = {
      'title': '我的卡片',
      'content': '卡片内容'
    }
    return formBindingData.createFormBindingData(formData)
  }

  onUpdateForm(formId: string) {
    console.log('卡片更新:' + formId)
  }

  onRemoveForm(formId: string) {
    console.log('卡片移除:' + formId)
  }
}

配置卡片(module.json5)

{
  "module": {
    "abilities": [
      {
        "name": "EntryFormAbility",
        "srcEntry": "./ets/entryformability/EntryFormAbility.ets",
        "description": "卡片扩展",
        "type": "form",
        "exported": false,
        "metadata": [
          {
            "name": "ohos.extension.form",
            "resource": "$profile:form_config"
          }
        ]
      }
    ]
  }
}

实战案例:音乐播放服务

ServiceExtensionAbility(后台服务)

// entryability/MusicService.ets
import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'
import Want from '@ohos.app.ability.Want'

export default class MusicService extends ServiceExtensionAbility {
  onStart(want: Want) {
    console.log('MusicService onStart')
    // 启动后台播放
    this.startMusicPlayback()
  }

  onCommand(want: Want, startId: number) {
    console.log('MusicService onCommand:' + JSON.stringify(want.parameters))
    // 处理客户端命令
    const command = want.parameters?.command
    if (command === 'play') {
      this.startMusicPlayback()
    } else if (command === 'pause') {
      this.pauseMusicPlayback()
    }
  }

  onDestroy() {
    console.log('MusicService onDestroy')
    // 清理资源
    this.stopMusicPlayback()
  }

  startMusicPlayback() {
    console.log('开始播放音乐')
    // 实际项目中这里会调用媒体播放API
  }

  pauseMusicPlayback() {
    console.log('暂停播放音乐')
  }

  stopMusicPlayback() {
    console.log('停止播放音乐')
  }
}

启动服务

// pages/Index.ets
import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'

@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext

  startService() {
    const want: Want = {
      bundleName: 'com.example.myapp',
      abilityName: 'MusicService',
      parameters: {
        command: 'play'
      }
    }

    this.context.startAbility(want)
      .then(() => console.log('启动服务成功'))
      .catch((err: BusinessError) => console.error('启动服务失败:' + JSON.stringify(err)))
  }

  stopService() {
    const want: Want = {
      bundleName: 'com.example.myapp',
      abilityName: 'MusicService'
    }

    this.context.stopAbility(want)
      .then(() => console.log('停止服务成功'))
      .catch((err: BusinessError) => console.error('停止服务失败:' + JSON.stringify(err)))
  }

  build() {
    Column() {
      Button('启动音乐服务')
        .onClick(() => this.startService())
        .margin(8)

      Button('停止音乐服务')
        .onClick(() => this.stopService())
        .margin(8)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

总结

本文涵盖的2025-2026纯血鸿蒙Stage模型进阶知识点:

  1. ✅ 多Ability通信(Want、EventHub)
  2. ✅ Ability启动模式(singleton、multiton、specified)
  3. ✅ 数据持久化(AppStorage、Preferences、RDB)
  4. ✅ 窗口高级管理(属性设置、键盘避让)
  5. ✅ ExtensionAbility开发(FormExtensionAbility、ServiceExtensionAbility)
  6. ✅ 实战:音乐播放服务

参考资料


最后更新:2026年5月 | 基于 HarmonyOS 6.1