鸿蒙NEXT元服务初体验

536 阅读9分钟

元服务&卡片基础

1 基本概念

官方介绍: 元服务(原名为原子化服务)HarmonyOS提供的一种面向未来的服务提供方式,是有独立入口的(用户可通过点击服务卡片打开元服务)、免安装的(无需显式安装,由系统程序框架后台安装后即可使用)用户应用程序

例如:一个传统新闻类应用A,在按照元服务理念调整设计后,将“新闻排行”独立为一个元服务A* ,使用户无需安装应用A即可通过桌面服务卡片快速浏览热点新闻。

元服务基于HarmonyOS API开发,支持运行在1+8+N设备上,供用户在合适的场景、合适的设备上便捷使用。元服务相对于传统应用形态更加轻量,同时提供更丰富的入口、更精准的分发。

简而言之,元服务就是一个用户手动无需安装的应用程序,和小程序有点类似,但是并不一样:

  1. 小程序:需要依赖于某个应用程序(比如微信,支付宝,抖音...等等)才可以运行
  1. 元服务:直接系统层面支持,无需额外的安装应用

下面附上官方的对比:

项目元服务传统应用
软件包形态App Pack(.app)App Pack(.app)
分发平台由应用市场(AppGallery)管理和分发由应用市场(AppGallery)管理和分发
安装后有无桌面icon无桌面icon,但可手动添加到桌面,显示形式为服务卡片有桌面icon
HAP免安装要求所有HAP(包括Entry HAP和Feature HAP)均需满足免安装要求所有HAP(包括Entry HAP和Feature HAP)均为非免安装的

结合上述内容,咱们学习元服务,核心点主要有2个:

元服务开发(应用核心功能)

  • 页面开发
  • 功能开发

卡片开发

  • 卡片页面
  • 卡片事件
  • 卡片数据

2 创建元服务

  1. 若首次打开DevEco Studio,请选择Create Project开始创建一个新工程。如果已经打开了一个工程,请在菜单栏选择File > New > Create Project来创建一个新工程。选择Atomic Service元服务开发,选择“Empty Ability”模板,单击Next进行下一步配置。

  1. 进入配置工程界面,修改“Project name”,Compile SDK选择“3.1.0(API 9)”,其他参数保持默认设置即可。

📌说明 :支持使用ArkTS低代码开发方式。低代码开发方式具有丰富的UI界面编辑功能,通过可视化界面开发方式快速构建布局,可有效降低开发者的上手成本并提升开发者构建UI界面的效率。如需使用低代码开发方式,请打开上图中的Enable Super Visual开关。

  1. 单击Finish,工具会自动生成示例代码和相关资源,等待工程创建完成。

3 项目结构

📌创建完毕的项目结构之前的应用类似,目前主要关注3个不同点即可:

\1. 卡片生命周期管理文件(EntryFormAbility.ts)

\2. 卡片页面文件(WidgetCard.ets)

\3. 卡片配置文件(form_config.json)

其他的和之前创建的应用是一致的,直接套用之前的理解即可,详细的说明如下:

  • AppScope > app.json5:元服务的全局配置信息。
  • entry:HarmonyOS工程模块,编译构建生成一个HAP。
    • src > main > ets:用于存放ArkTS源码。
    • src > main > ets > entryability:元服务的入口。
    • src > main > ets > entryformability:卡片生命周期管理文件。
    • src > main > ets > pages:元服务包含的页面。
    • src > main > ets > widget > pages:元服务工程创建时,会自动生成一个服务卡片页面,在本示例中作为元服务的默认卡片。
    • src > main > resources:用于存放元服务所用到的资源文件,如图形、多媒体、字符串、布局文件等。关于资源文件,详见资源分类与访问
    • src > main > resources > base > profile > form_config.json:元服务卡片配置文件
    • src > main > module.json5:模块配置文件。主要包含HAP的配置信息、元服务在具体设备上的配置信息以及元服务的全局配置信息。具体的配置文件说明,详见module.json5
    • build-profile.json5:当前的模块信息 、编译信息配置项,包括buildOption、targets配置等。
    • hvigorfile.ts:模块级编译构建任务脚本,开发者可以自定义相关任务和代码实现。
  • oh_modules:用于存放三方库依赖信息。关于原npm工程适配ohpm操作,请参考历史工程手动迁移
  • build-profile.json5:元服务级配置信息,包括签名signingConfigs、产品配置products等。其中products中可配置当前运行环境,默认为HarmonyOS。
  • hvigorfile.ts:元服务级编译构建任务脚本。
  • EntryCard:元服务卡片快照图片存放目录。

4 元服务页面开发

咱们先从熟悉的页面开发入手,因为元服务的页面开发和之前学习的应用开发没有差异,之前学习的所有内容都可以直接在这里使用,接下来咱们来实现一个简单的效果:

  1. 页面Index 点击Next 跳转 页面Second
  1. 页面Second 点击Back 返回 页面Index

4.1 页面结构开发

咱们首先来实现2个页面的基本结构,然后再去实现页面跳转

  1. 调整Index.ets代码为:
// Index.ets
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
​
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        // 添加按钮,以响应用户点击
        Button() {
          Text('Next')
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
        }
        .type(ButtonType.Capsule)
        .margin({
          top: 20
        })
        .backgroundColor('#0D9FFB')
        .width('40%')
        .height('5%')
      }
      .width('100%')
    }
    .height('100%')
  }
}
  1. 在pages目录下继续添加页面 Second.ets ,并编写代码

// Second.ets
@Entry
@Component
struct Second {
  @State message: string = 'Hi there'
​
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button() {
          Text('Back')
            .fontSize(25)
            .fontWeight(FontWeight.Bold)
        }
        .type(ButtonType.Capsule)
        .margin({
          top: 20
        })
        .backgroundColor('#0D9FFB')
        .width('40%')
        .height('5%')
      }
      .width('100%')
    }
    .height('100%')
  }
}

4.2 增加跳转逻辑

接下来实现页面Index.ets和页面Second之间互相跳转

  1. Index.ets按钮增加 跳转逻辑

// Index.ets
// 导入页面路由模块
import router from '@ohos.router';
​
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        // 添加按钮,以响应用户点击
        Button() {
          Text('Next')
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
        }
        .type(ButtonType.Capsule)
        .margin({
          top: 20
        })
        .backgroundColor('#0D9FFB')
        .width('40%')
        .height('5%')
         // 跳转按钮绑定onClick事件,点击时跳转到第二页
        .onClick(() => {
          router.pushUrl({ url: 'pages/Second' })
        }) 
      }
      .width('100%')
    }
    .height('100%')
  }
}
  1. Second.ets 给按钮增加返回逻辑

// Second.ets
// 导入页面路由模块
import router from '@ohos.router';
​
@Entry
@Component
struct Second {
  @State message: string = 'Hi there'build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button() {
          Text('Back')
            .fontSize(25)
            .fontWeight(FontWeight.Bold)
        }
        .type(ButtonType.Capsule)
        .margin({
          top: 20
        })
        .backgroundColor('#0D9FFB')
        .width('40%')
        .height('5%')
         // 返回按钮绑定onClick事件,点击按钮时返回到第一页
        .onClick(() => {
          router.back()
        }) 
      }
      .width('100%')
    }
    .height('100%')
  }
}
  1. 打开Index.ets文件,单击预览器中的刷新按钮进行刷新。效果如下图所示

📌划重点:元服务中界面的开发和之前应用界面的开发基本一致,直接套用即可

5 默认卡片WidgetCard.ets

因为元服务不提供桌面应用图标,我们可以通过用户手动的方式在桌面上添加一张卡片,通过点击卡片来唤起元服务。

卡片特点:

  1. 卡片可以承载少量的内容显示和交互
  1. 卡片可以充当元服务的入口,点击卡片可以唤起元服务

📌注意!!

\1. 普通应用中也可以添加服务卡片并进行服务卡片开发,但是默认并没有添加卡片\2. 元服务因为没有icon作为入口,所以默认提供了一张服务卡片作为入口

上一节咱们了解了一下元服务页面的开发,和之前的应用开发是基本一样的。

接下来咱们来看元服务中另外一个非常重要的部分-服务卡片。

5.1 默认卡片文件


在项目的如下路径有一个ets文件,此文件就是默认卡片文件,我们可以在里面定制属于自己的显示内容
src/main/ets/widget/pages/WidgetCard.ets

咱们先将默认卡片调整为如下效果:

  1. 页面结构
  1. 点击动画

5.2 卡片结构

  1. 删掉默认内容,使用如下内容进行替换
  1. 使用预览器测试效果

源码


// WidgetCard.ets
@Entry
  @Component
  struct WidgetCard {
    @State x: number = 1
    @State y: number = 1
​
    build() {
      Column() {
        Button('Click to enlarge')
          .onClick(() => {
            this.x = 1.1
            this.y = 1.1
          })
          .scale({ x: this.x, y: this.y })
          .animation({
            curve: Curve.Linear,
            duration: 200,
            onFinish: () => {
              this.x = 1
              this.y = 1
            }
          })
      }
      .padding(10)
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)
    }
  }

从编写的代码来看,和之前应用开发中的基本一致,但是支持的能力并没有应用中多,这里附上官方说明链接:

  1. 卡片页面能力说明
  1. 卡片使用动效能力

5.3 服务卡片跳转元服务

通过在服务卡片的最外层容器添加点击事件,然后通过postCardAction方式可以拉起它的元服务。

更为深入的内容之后有专门的章节进行讲解,这里先演示看看:

  1. 调整代码
  1. 添加卡片到桌面(模拟器 or 真机调试)
  1. 测试跳转

注: 跳转元服务的功能无法通过预览器调试,需要借助模拟器 或 真机

  1. 调整代码:最外层容器增加点击事件,实现点击跳转元服务

@Entry
@Component
struct WidgetCard {
  @State x: number = 1
  @State y: number = 1build() {
    Column() {
      Button('Click to enlarge')
        .onClick(() => {
          this.x = 1.1
          this.y = 1.1
        })
        .scale({ x: this.x, y: this.y })
        .animation({
            curve: Curve.Linear,
            duration: 200,
            onFinish: () => {
              this.x = 1
              this.y = 1
            }
        })
    }
    .padding('10vp')
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
     .onClick(() => {
      // 通过postCardAction 实现跳转
      // 代码细节之后展开
      postCardAction(this, {
        "action": 'router',
        "abilityName": 'EntryAbility',
        "params": {
          "message": 'router test'
        }
      });
    }) 
  }
}
  1. 模拟器 or 真机:添加卡片到桌面
    1. 启动之后切换到桌面
    2. 捏合两指
    3. 模拟器 windows: ctrl + 鼠标左键
    4. 模拟器 mac: command + 鼠标左键
    5. 点击服务卡片
    6. 拉到底部,选择其他服务卡片
    7. 选择刚刚的元应用(这里是 MyApplication
    8. 找到卡片,点击添加到桌面

  1. 测试跳转:点击按钮以外的空白区域,即可实现跳转

至此,咱们已经体验了元服务的核心内容

  1. 元服务创建:选择Atomic Service
  1. 页面开发:和应用中的页面开发一样,直接套用之前的经验即可
  1. 卡片开发:界面开发类似应用开发,通过postCardAction可以与主应用通信。

  postCardAction(this, {
        "action": 'router',
        "abilityName": 'EntryAbility',
        "params": {
          "message": 'router test'
        }
      });