上个月,公司决定把最核心的“扫码乘车”功能,剥离出来做成鸿蒙的元服务。元服务不需要用户去应用市场下载安装,扫一扫或者碰一碰就能直接拉起。这听起来很酷,但它的开发形态与传统 App 有巨大的差异,尤其是在包体积和卡片联动的限制上,极其苛刻。

元服务的瘦身与工程配置

元服务的核心理念是“即用即走”。如果你的包体积超过了几兆,系统会直接拒绝上架。我们在剥离代码时,把底层的三方统计库、复杂的图片渲染库全部砍掉,只保留了最基础的 ArkUI 和网络请求。

在 module.json5 中,必须明确声明该模块为元服务类型:

json

{
  "module": {
    "name": "entry",
    "type": "entry",
    "installationFree": true // 核心标识,声明为免安装
  }
}

注意:installationFree 设置后,在本地调试时,你必须使用特定的元服务签名,且需要在 DevEco Studio 的启动配置里勾选“Deploy as Atomic Service”。否则,打包出来的依然是普通 HAP 包,无法测试免安装拉起的效果。

桌面卡片的免安装联动

为了让用户不用扫码也能快速乘车,我们需要提供一个桌面卡片。卡片和元服务之间的数据交互,是这里的重头戏。

卡片本身是一个没有生命周期的 UI 壳子,所有的数据刷新都要依靠 FormExtensionAbility。当用户在元服务里开通了乘车码,我们需要立刻通知卡片更新状态。

typescript

import formProvider from '@ohos.app.form.formProvider';
import formBindingData from '@ohos.app.form.formBindingData';

async function updateTicketCard(formId: string, status: string) {
  let formData = {
    cardStatus: status, // 如 '已开通'
    updateTime: new Date().toLocaleTimeString()
  };
  let bindingData = formBindingData.createFormBindingData(formData);
  
  try {
    // 主动推送到桌面卡片
    await formProvider.updateForm(formId, bindingData);
  } catch (err) {
    console.error('卡片更新失败', err);
  }
}

警示:元服务的进程极容易被系统冻结,千万不要在元服务里用长连接去死等数据更新。卡片的更新逻辑应该是事件驱动的(比如用户点击了元服务里的“充值”按钮,成功后立刻调一次 updateForm)。

拉起元服务的正确姿势

如果你是一个网页或者第三方 App,怎么拉起你的元服务?这里必须使用 App Linking 配合特定的 URL 规则。

在 module.json5 里配置 skills,匹配你的业务域名。当系统识别到匹配的 URL 时,会直接分发拉起元服务。但如果用户手机上已经装了你的完整版 App,系统通常会优先拉起 App。

为了让用户强制进入元服务,我们使用了底层的 WantAgent,并在参数中声明只拉起免安装版本。

typescript

let wantAgentInfo: wantAgent.WantAgentInfo = {
  wants: [
    {
      bundleName: 'com.example.transit',
      abilityName: 'EntryAbility',
      parameters: { 
        // 标识拉起场景
        launchType: 'from_scanner'
      }
    }
  ],
  actionType: wantAgent.OperationType.START_ABILITY,
  requestCode: 0
};

在一个全新的鸿蒙工程里,创建一个元服务模块,并在里面放置一个静态的文本卡片。通过扫码或者网页链接的方式,尝试把这个元服务拉起。当你看到屏幕上出现“免安装运行”的标识时,你就算真正踏入了鸿蒙生态的轻量化大门。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐