Appearance
通知系统(Notification)
1. 通知系统架构
通知系统架构:
┌─────────────────────────────────────────────┐
│ 应用层 │
│ └── 构建 Notification │
├─────────────────────────────────────────────┤
│ Notification Manager │
│ ├── 通知渠道管理 │
│ ├── 通知分类/优先级 │
│ └── 通知聚合/折叠 │
├─────────────────────────────────────────────┤
│ Notification Service │
│ ├── 状态栏通知(StatusBar) │
│ ├── 横幅通知(Banner) │
│ ├── 锁屏通知 │
│ └── 媒体通知 │
├─────────────────────────────────────────────┤
│ 分发层 │
│ ├── 本地通知(推送) │
│ └── 远程通知(Push Kit) │
└─────────────────────────────────────────────┘2. 通知类型
| 类型 | 说明 | 展示位置 |
|---|---|---|
| 普通通知 | 文本+图片+按钮 | 状态栏 + 通知抽屉 |
| 横幅通知 | 弹窗式通知,自动消失 | 屏幕顶部浮动 |
| 大通知 | 可展开的详细通知 | 状态栏 + 通知抽屉 |
| 媒体通知 | 音乐播放控制 | 媒体中心 |
| 进度通知 | 显示下载/上传进度 | 状态栏 |
| 远程通知 | 通过 Push Kit 推送 | 状态栏 + 通知抽屉 |
| 表单通知 | 卡片式通知(Form) | 桌面/锁屏 |
3. 通知构建与发送
3.1 本地通知
arkts
import { notification } from '@kit.BasicServicesKit';
// 1. 创建通知渠道(Android 10+ 必需)
const channelId = 'my_channel';
const channel: notification.NotificationChannel = {
name: '重要通知',
channelDescription: '用于重要事件的通知渠道',
importance: notification.Importance.IMPORTANCE_HIGH, // 高重要性
enableLights: true,
lightColor: '#FF0000',
lockscreenVisibility: notification.LockscreenVisibility.VISIBILITY_PUBLIC,
};
// 创建通知渠道
await notification.createNotificationChannel(channelId, channel);
// 2. 构建通知内容
const template: notification.NotificationContent = {
normal: {
title: '新消息',
text: '您有一条新消息,点击查看',
extraInfo: 'extra info',
normalExtracInfo: {
clickIntent: {
parameters: {
url: 'https://example.com'
}
},
action: notification.Action.ACTION_TYPE_CLICK,
}
},
large: {
title: '新消息详情',
largePicPath: '/data/user/0/com.example/files/image.jpg',
largeText: '这是一条很长的通知内容,用于展示详细信息。'
}
};
// 3. 创建并发送通知
const request: notification.Request = {
content: template,
id: 1001,
channelId: channelId,
normal: {
advancedNormalContent: {
clickIntent: {
parameters: { url: 'https://example.com' },
action: notification.Action.ACTION_TYPE_CLICK
}
}
}
};
await notification.publishNotification(request);3.2 横幅通知(Banner)
arkts
import { banner } from '@kit.BasicServicesKit';
// 创建横幅通知
const bannerRequest: banner.Request = {
bannerType: banner.BannerType.NORMAL,
template: {
title: '提示',
text: '这是一条横幅通知'
},
action: {
clickIntent: {
parameters: { type: 'banner_click' },
action: banner.Action.ACTION_TYPE_CLICK
}
}
};
const bannerId = await banner.publish(bannerRequest);
// 自动消失(3 秒后)
setTimeout(async () => {
await banner.cancel(bannerId);
}, 3000);3.3 进度通知
arkts
import { notification } from '@kit.BasicServicesKit';
// 进度通知(下载/上传)
const progressRequest: notification.Request = {
content: {
normal: {
title: '文件下载中',
text: '正在下载...',
normalExtracInfo: {
clickIntent: {
parameters: { url: 'detail' },
action: notification.Action.ACTION_TYPE_CLICK
}
}
}
},
id: 2001,
channelId: 'download_channel',
normal: {
progress: {
max: 100,
current: 50,
style: notification.ProgressStyle.PROGRESS_STYLE_INDETERMINATE
}
}
};
// 更新进度
const updateRequest: notification.Request = {
content: progressRequest.content,
id: progressRequest.id,
channelId: progressRequest.channelId,
normal: {
progress: {
max: 100,
current: 75, // 更新进度
style: notification.ProgressStyle.PROGRESS_STYLE_NORMAL
}
}
};
await notification.updateNotification(updateRequest);4. 通知渠道管理
4.1 渠道概念
通知渠道(Notification Channel):
├── 应用可以创建多个渠道,每个渠道代表一类通知
├── 用户可以独立设置每个渠道的行为
├── 渠道一旦创建,只能修改不可见性(重要性和可关闭性)
├── 不同渠道可以有不同的重要性级别
└── 用户关闭渠道后,该渠道通知不再展示4.2 渠道配置
arkts
import { notification } from '@kit.BasicServicesKit';
// 重要性级别(从高到低)
const IMPORTANCE_LEVELS = {
MAX: notification.Importance.MAX, // 震动 + 响铃 + 横幅
HIGH: notification.Importance.HIGH, // 响铃 + 横幅
NORMAL: notification.Importance.NORMAL, // 横幅
LOW: notification.Importance.LOW, // 仅状态栏
MIN: notification.Importance.MIN, // 不展示(仅通知抽屉)
};
// 创建多个渠道
const channels: notification.NotificationChannel[] = [
{
name: '消息通知',
channelDescription: '消息相关通知',
importance: notification.Importance.HIGH,
enableVibration: true,
lockscreenVisibility: notification.LockscreenVisibility.VISIBILITY_PUBLIC,
},
{
name: '系统通知',
channelDescription: '系统相关通知',
importance: notification.Importance.NORMAL,
lockscreenVisibility: notification.LockscreenVisibility.VISIBILITY_PRIVATE,
},
{
name: '推广通知',
channelDescription: '营销推广通知',
importance: notification.Importance.LOW,
lockscreenVisibility: notification.LockscreenVisibility.VISIBILITY_SECRET,
}
];
for (const channel of channels) {
await notification.createNotificationChannel('channel_' + channel.name, channel);
}5. 远程通知(Push Kit)
5.1 Push Kit 架构
Push Kit 推送流程:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 服务端 │─────│ Agconnect │─────│ 推送服务 │─────│ 设备端 │
│ (APNs) │ │ (AGC) │ │ (HMS/Push)│ │ (App) │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │ │ │
└──────── 云端消息通道 ──────────────┘5.2 Push Kit 配置
arkts
// 1. 在 module.json5 中声明权限
{
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
// 2. 初始化 Push Kit
import { push } from '@kit.PushKit';
async function initPush() {
// 获取推送 Token
const token = await push.getToken();
console.log('Push Token: ' + token);
// 监听 Token 刷新
push.on('token', (newToken: string) => {
console.log('Token refreshed: ' + newToken);
});
// 监听消息(App 在前台时)
push.on('message', (msg: push.PushMessage) => {
if (msg.data) {
console.log('Push data: ' + msg.data);
// 收到前台推送,可显示本地通知
}
});
}
// 3. 处理通知点击
push.on('click', (msg: push.PushMessage) => {
// 用户点击通知,执行对应操作
router.pushUrl({
url: 'pages/Detail',
params: { data: msg.data }
});
});5.3 通知消息处理
arkts
// 消息处理策略
enum PushMessageHandler {
// 1. 自动展示(默认)
// 不需要额外代码,系统自动展示通知
// 2. 自定义处理(前台消息)
onMessage(msg: push.PushMessage) {
// 根据消息类型做不同处理
switch (msg.type) {
case 'message':
showLocalNotification(msg);
break;
case 'command':
handleCommand(msg.data);
break;
case 'silent':
// 静默消息,不展示通知,只更新数据
updateData(msg.data);
break;
}
},
}6. 通知与 Android 对比
| 维度 | Android | 鸿蒙 |
|---|---|---|
| 通知构建 | Notification.Builder | notification.NotificationBuilder |
| 通知渠道 | NotificationChannel | NotificationChannel |
| 横幅通知 | 原生支持 | Banner API |
| 远程推送 | FCM / 厂商 Push | Push Kit (AGC) |
| 通知点击 | PendingIntent | clickIntent (Want) |
| 大通知 | setStyle(Notif.BigText) | large 属性 |
| 进度通知 | setProgress() | normal.progress |
| 通知渠道创建 | 代码创建(不可删除) | 代码创建(仅可不可见) |
7. 🎯 面试高频考点
Q1: 鸿蒙通知系统的工作原理?
答要点:
- 通知通过 Notification Manager 管理,分为本地通知和远程通知
- 本地通知通过 notification.publishNotification() 发送
- 远程通知通过 Push Kit 实现,通过云端(AGC)推送
- 通知渠道是 Android 10+ 的概念,鸿蒙同样采用
- 用户可在设置中管理每个渠道的展示行为
- 通知可包含点击 Intent,跳转到指定页面
Q2: Push Kit 与 FCM 的区别?
答要点:
- Push Kit 是鸿蒙生态的推送服务,通过 AGC(AppGallery Connect)
- FCM 是 Google 的推送服务,鸿蒙 NEXT 不再支持 GMS/FCM
- Push Kit 支持国内网络环境,FCM 在国内不可用
- Push Kit 的 Token 通过 AGC SDK 获取,FCM 通过 Firebase SDK
- Push Kit 支持消息类型:消息/指令/静默
Q3: 如何实现通知的自定义样式?
答要点:
- 通过 NotificationTemplate 定义样式(normal/large/banner)
- 使用 large 属性实现大通知(大图/长文本)
- 使用 Banner API 实现横幅通知
- 使用 action 属性添加通知内按钮
- 使用 clickIntent 实现点击跳转
- 通过 importance 控制通知的重要性级别
💡 面试提示:重点掌握 通知渠道、本地/远程通知区别、Push Kit 推送流程。对比 Android 的 Notification 体系。