TUIKit ArkUI 是基于腾讯云 IM SDK 的一套 鸿蒙 ArkUI 组件库,提供了聊天、会话列表、联系人管理等即时通信功能的完整解决方案。本文介绍如何手动集成该组件并实现核心功能。完成本集成后,您的鸿蒙应用将具备聊天、会话列表、联系人管理等即时通信能力,并可选配音视频通话功能。
关键概念
TUIKit ArkUI 提供了一套完整的即时通信 UI 组件,向下依赖 AtomicXCore 数据层,向上可构建各种功能性 Page。
Page 层:基于 TUIKit ArkUI 封装的完整功能页面:ChatPage、ContactsPage、ConversationsPage,可直接使用。
TUIKit ArkUI(UI 组件层):基于 AtomicXCore 构建的 ArkUI 组件,可嵌套到已有的 App 页面中。
AtomicXCore(数据层):提供数据管理和业务逻辑,包含各种 Store 和 Manager。
前提条件
DevEco Studio 5.0 及以上版本。
HarmonyOS SDK API 15 及以上版本。
一个有效的腾讯云账号及 Chat 应用。可参见 开通服务 从控制台获取以下信息:
SDKAppID:App 在控制台获取的 Chat 应用的 ID,为应用的唯一标识。
SDKSecretKey:应用的密钥。
说明:
本项目目前仅支持手动集成,暂不支持通过 ohpm 管理器集成。
集成并引入组件
下载源码
git clone https://cnb.cool/tencent/cloud/trtc/TUIKit_Harmony// 或者 git clone https://github.com/Tencent-RTC/TUIKit_Harmony.git
项目目录结构说明:
atomic_x/ # TUIKit ArkUI(UI 组件层)│ ├── src/main/ets/│ │ ├── messagelist/ # 消息列表组件│ │ ├── messageinput/ # 消息输入组件│ │ ├── conversationlist/ # 会话列表组件│ │ ├── contactlist/ # 联系人列表组件│ │ ├── chatsetting/ # 聊天设置组件│ │ ├── basecomponent/ # 基础组件│ │ └── ... # 其他UI组件│ └── src/main/resources/ # 资源文件chat/├── uikit/ # Page 层(参考实现)│ └── src/main/ets/pages/│ ├── ChatPage.ets # 聊天页面│ ├── ConversationsPage.ets # 会话列表页面│ └── ContactsPage.ets # 联系人页面└── demo/ # 示例应用(可选参考)│call/ # 音视频通话组件(推荐集成)└── tuicallkit/ # TUICallKit ArkUI,一行代码在聊天中拉起音视频通话
说明:
TUIKit_Harmony 是包含多个产品的开源仓库,Chat 的 UI 源码位于
chat/ 目录下(chat/uikit 为 UIKit 组件库,chat/demo 为示例工程),其依赖的基础组件 atomic_x 与音视频通话组件 call/ 位于仓库根目录。集成组件
1. 将组件目录完整复制到您的鸿蒙项目中,如下图所示,其中 chat/demo 是示例项目,atomic_x 是从 GitHub 上下载的组件源码,依赖关系如下:


2. 在项目 entry 的 oh-package.json5 中添加以下依赖:
说明:
atomic_x 可以放在任何位置,只要在 oh-package.json5 中正确设置相对路径即可。
{"name": "entry","version": "1.0.0","description": "Please describe the basic information.","main": "","author": "","license": "","dependencies": {"@tencentcloud/atomicxcore": "^5.0.0","@tencentcloud/atomicx": "file:../../../atomic_x","chatuikit": "file:../../uikit","@tencentcloud/tuicallkit": "file:../../../call",//其他依赖项"@tencent/mmkv": "1.3.5","@ohos/axios": "2.1.1","dayjs": "^1.11.7"},"devDependencies": {"pako": "^2.1.0","@ohos/crypto-js": "^2.0.1"}}
3. oh-package.json5 修改完毕后,执行以下命令,安装本地 TUIKit 组件。示例:
ohpm install
ohpm install 会自动安装所需的依赖库。
注意:
使用本地集成方案时,如需升级时需要从 GitHub 获取最新的组件代码,覆盖您本地项目的 atomic_x 目录。
当私有化修改和远端有冲突时,需要手动合并,处理冲突。
配置项目
1. 配置 Build Settings
在项目的 Build Settings 中添加以下配置:
Compatible SDK:5.0.3(15) 及以上

项目签名配置

2. 配置 module.json5,路径如 “entry/src/main/module.json5”
添加必要的权限配置:
"requestPermissions": [{"name": "ohos.permission.GET_NETWORK_INFO"},{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.MICROPHONE","reason": "$string:permission_microphone","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}},{"name": "ohos.permission.CAMERA","reason": "$string:permission_camera","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}}]
3. 模块声明
已有项目集成源码后,需在 build-profile.json5 文件声明模块:
"modules": [{"name": "entry","srcPath": "./entry","targets": [{"name": "default","applyToProducts": ["default"]}]},{"name": "atomic_x","srcPath": "./atomic_x", //根据实际目录调整"targets": [{"name": "default","applyToProducts": ["default"]}]},{"name": "chatuikit","srcPath": "./chat/uikit" //根据实际目录调整},{"name": "tuicallkit","srcPath": "./chat/call" //根据实际目录调整}]
4. EntryAbility 必须初始化
在
EntryAbility.ets 中需要完成 MMKV 与 ContextProvider 两个关键组件的初始化:import { MMKV } from '@tencent/mmkv';import { ContextProvider } from '@tencentcloud/atomicx/src/main/ets/basecomponent/Index';import { TUICallKit } from '@tencentcloud/tuicallkit';export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {// 1. MMKV 初始化MMKV.initialize(this.context.getApplicationContext());// 2. ContextProvider 初始化ContextProvider.init(this.context);}onWindowStageCreate(windowStage: window.WindowStage): void {windowStage.loadContent('pages/SplashScreenPage', (err) => {TUICallKit.createInstance(this.context).attach(windowStage);});}onWindowStageDestroy(): void {TUICallKit.createInstance(this.context).detach();}onConfigurationUpdate(newConfig: Configuration): void {// 3.响应系统配置变更(深色模式、语言切换等)ContextProvider.onConfigurationUpdate(newConfig);}}
接入步骤
步骤1:配置用户鉴权
为快速验证功能,您可以参考 TUIKit_Harmony 源码中
chat/demo/entry/src/main/ets/signature/GenerateTestUserSig.ts 的实现来生成 UserSig。请将该文件或类似逻辑复制到您的项目中,并填入以下参数:SDKAPPID:请设置为 步骤1 中获取的实际应用 SDKAppID。
SECRETKEY:请设置为 步骤2 中获取的实际密钥信息。

步骤2:用户登录
登录组件后才能正常使用组件的功能。用户在 App 上点击登录时,可调用 LoginStore 登录 TUIKit ArkUI 组件。
示例代码如下所示:
import { LoginStore } from '@tencentcloud/atomicxcore';// 用户登录LoginStore.shared().login(SDKAPPID, this.userID, userSig, getContext()).then(() => {// login success}).catch((reason: Object) => {// login failed});
警告:
步骤3:构建会话列表界面
可基于 TUIKit ArkUI 中的 ConversationList 组件,构建一个会话列表页面。ConversationList 内建的功能是:
展示用户的会话列表,包含单聊和群聊会话。
支持用户操作单个会话:置顶、删除、清空会话消息等。
可将 ConversationList 直接集成到现有的 App 页面中,也可新构建一个完整的会话列表页,组装后的一种 UI 效果如下图所示:

将 ConversationList 封装为会话列表页,可参考
chat/uikit/ConversationsPage.ets 文件里的实现,ConversationsPage 主要做了以下工作:1. 在 ConversationList 上方添加了 headerView。
2. 实现点击会话列表 cell 事件。
3. 支持创建会话和群组功能:
3.1 点击右上角 "+" 按钮可以创建新会话或群组。
3.2 支持从联系人列表选择好友创建单聊。
3.3 支持选择多个好友创建群聊。
核心示例代码如下所示:
import { ConversationList } from '@tencentcloud/atomicx/src/main/ets/conversationlist/Index';import { ThemeState } from '@tencentcloud/atomicx/src/main/ets/basecomponent/Index';import { ConversationInfo } from '@tencentcloud/atomicxcore';@Componentexport struct ConversationsPage {@State showAddMenu: boolean = false;build() {Stack({ alignContent: Alignment.TopStart }) {Column() {this.LargeTitleBuilder()ConversationList({onConversationClick: (item: ConversationInfo) => {// Customize onConversationClick event},}).layoutWeight(1)}.width('100%').height('100%').backgroundColor(this.themeState.colors.bgColorOperate).onClick(() => {// Click + to show this menu.if (this.showAddMenu) {this.showAddMenu = false;}})if (this.showAddMenu) {Row().width('100%').height('100%').backgroundColor('rgba(0, 0, 0, 0)').onClick(() => {this.showAddMenu = false;})}if (this.showAddMenu) {this.AddMenuDialog()}}.width('100%').height('100%')}@BuilderLargeTitleBuilder() {Row() {Text($r('app.string.chat_title')).fontSize(34).fontWeight(FontWeight.Bold).fontColor(this.themeState.colors.textColorPrimary).layoutWeight(1)Row() {Image($r('app.media.new_chat_icon')).width(24).height(24).onClick(() => {this.showAddMenu = true;})}}.width('100%').height(52).padding({ left: 16, right: 16 }).backgroundColor(this.themeState.colors.bgColorOperate)}}
步骤4:音视频通话
TUICallKit 的初始化分两个阶段:
1. 应用启动阶段(
EntryAbility):在 onWindowStageCreate 中调用 TUICallKit.createInstance(this.context).attach(windowStage),以支持全局通话能力(参见上文「EntryAbility 必须初始化」)。2. 登录成功后(业务页面):在业务页面(如 HomePage)中订阅
call.startCall 事件,即可在 Chat 组件中正常使用音视频通话功能。@Entry@Componentstruct HomePage {private callEventObserver?: TUIObserver;aboutToAppear(): void {// 初始化 CallKit 并订阅通话事件TUICallKit.createInstance(getContext());this.callEventObserver = new CallStartObserver();TUIEventBus.getInstance().subscribe('call.startCall', null, this.callEventObserver);}aboutToDisappear(): void {if (this.callEventObserver) {TUIEventBus.getInstance().unsubscribe('call.startCall', null, this.callEventObserver);}}}class CallStartObserver implements TUIObserver {onNotify(event: string, _key: string | null, params: NotifyParams | null): void {if (event === 'call.startCall' && params?.data) {const data = params.data;const participantIds: string[] = (data['participantIds'] as string[]) ?? [];const chatGroupId: string = (data['chatGroupId'] as string) ?? '';const timeout: number = (data['timeout'] as number) ?? 30;let callParams = new CallKitParams('', timeout, '', chatGroupId);TUICallKit.createInstance(getContext()).calls(participantIds, CallKitMediaType.video, callParams);}}}
步骤5:构建聊天界面
可基于 TUIKit ArkUI 中的 MessageList、MessageInput 组件,构建一个聊天页面。
MessageList 内建的功能是:
展示单聊或群聊消息列表。
支持对单条消息操作:查看图片消息大图、播放视频或语音消息、复制文本消息、撤回消息、删除消息等。
MessageInput 内建的功能是:
支持用户组建并发送多种类型的消息:文本、表情、图片、语音、视频、文件等。
可将 MessageList 和 MessageInput 直接集成到现有的 App 页面中,也可新构建一个完整的聊天页,组装后的一种 UI 效果如下图所示:

将 MessageList 和 MessageInput 组装为聊天页,可参考
chat/uikit/ChatPage.ets 文件里的实现,ChatPage 主要做了以下工作:1. 在最上方添加了 headerView,展示会话的名称。
2. 按照移动端用户使用习惯,上下拼接 MessageList 和 MessageInput。
核心示例代码如下所示:
import { MessageList } from '@tencentcloud/atomicx/src/main/ets/messagelist/Index';import { MessageInput } from '@tencentcloud/atomicx/src/main/ets/messageinput/Index';import { Avatar, AvatarContentType, AvatarSize } from '@tencentcloud/atomicx/src/main/ets/basecomponent/Index';export struct ChatPage {...build() {Stack() {Column() {this.LargeTitleBuilder();MessageList({conversationID: this.conversationID,locateMessage: this.locateMessage,onUserClick: (userID: string) => {console.log(`[ChatPage] User avatar clicked: ${userID}`);}}).width('100%').layoutWeight(1)MessageInput({conversationID: this.conversationID,})}.width('100%').height('100%').backgroundColor(this.themeState.colors.bgColorOperate).expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])}.width('100%').height('100%')}@BuilderLargeTitleBuilder() {Column() {Row() {Row({ space: 8 }) {// Back buttonImage($rawfile('basecomponent/common_back_icon.svg')).width(24).height(24).fillColor(this.themeState.colors.textColorSecondary).onClick(() => {if (this.onBack) {this.onBack();}})Row({ space: 8 }) {// AvatarAvatar({content: {type: AvatarContentType.Image,url: this.avatarUrl,name: this.title || '',},avatarSize: AvatarSize.S,})Column() {Text(this.title).fontSize(14).fontColor(this.themeState.colors.textColorPrimary).fontWeight(FontWeight.Bold).textAlign(TextAlign.Start).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })Text(this.status).fontSize(12).fontColor(this.themeState.colors.textColorTertiary).fontWeight(FontWeight.Regular).textAlign(TextAlign.Start).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })}.alignItems(HorizontalAlign.Start).layoutWeight(1).constraintSize({ maxWidth: '60%' })}.layoutWeight(1).onClick(() => {this.navigateToProfile();})}.layoutWeight(1).alignItems(VerticalAlign.Center)}.width('100%').height(56).padding({ left: 10, right: 10 }).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.SpaceBetween)// DividerDivider().width('100%').height(0.3).color(this.themeState.colors.strokeColorSecondary)}.width('100%').backgroundColor(this.themeState.colors.bgColorOperate)}}
步骤6:构建联系人界面
可基于 TUIKit ArkUI 中的 ContactList 组件,构建一个联系人页面。ContactList 内建的功能是:
查看好友申请列表。
查看已加入的群列表。
处理群组邀请和申请。
管理黑名单列表。
查看好友。
可将 ContactList 直接集成到现有的 App 中,也可新构建一个完整的联系人列表页,组装后的一种 UI 效果如下图所示:

将 ContactList 封装为联系人列表页,可参考
chat/uikit/ContactsPage.ets 文件里的实现,ContactsPage 主要做了以下工作:1. 在 ContactList 上方添加了 headerView
2. 实现点击联系人列表 cell 事件。
3. 支持添加联系人和添加群组:
3.1 点击右上角 "+" 按钮可以添加联系人或群组。
3.2 支持根据 UserID 搜索目标联系人。
3.3 支持根据 GroupID 搜索目标群组。
核心示例代码如下所示:
import { ContactInfo } from '@tencentcloud/atomicxcore';import { ContactList } from '@tencentcloud/atomicx/src/main/ets/contactlist/Index';export struct ContactsPage {...build() {Stack({ alignContent: Alignment.TopStart }) {Column() {this.LargeTitleBuilder()ContactList({onContactClick: this.handleContactSelect,onGroupClick: this.handleGroupSelect,}).layoutWeight(1)}.width('100%').height('100%').backgroundColor(this.themeState.colors.bgColorOperate)}.width('100%').height('100%')}@BuilderLargeTitleBuilder() {Row() {Text($r('app.string.contacts_title')).fontSize(34).fontWeight(FontWeight.Bold).fontColor(this.themeState.colors.textColorPrimary).fontFamily('PingFang HK').layoutWeight(1)Row() {Image($r('app.media.new_chat_icon')).width(24).height(24).onClick(() => {this.showAddMenu = true;})}}.width('100%').height(ContactsPage.LARGE_TITLE_HEIGHT).padding({ left: 16, right: 16 }).backgroundColor(this.themeState.colors.bgColorOperate)}...}
步骤7:完善界面跳转逻辑
ConversationsPage、ChatPage、ContactsPage 中暴露了一些用户点击事件,可自定义事件来实现页面间的交互:
Page | 回调 | 建议跳转逻辑 |
ConversationsPage | onConversationClick: (ConversationInfo)?:(item: ConversationInfo) => void; | 点击会话列表中的会话时触发,建议跳转到聊天页面(ChatPage)。 |
ContactsPage | onContactClick?: (item: ContactInfo) => void; | 点击联系人 cell 时触发,建议跳转联系人详情页面(C2CChatSetting)。 |
| onGroupClick?: (item: ContactInfo) => void; | 点击群组 cell 时触发,建议跳转群聊页面(ChatPage)。 |
ChatPage | onUserClick?: (userID: string) => void; | 点击消息中的用户头像或昵称时触发,建议跳转用户信息页(C2CChatSetting)。 |
| onChatHeaderClick?: (conversationID:string) => void; | 点击导航栏中的头像时触发,建议跳转用户信息页(C2CChatSetting)或群聊信息页(GroupChatSetting) |
| onBack?: () => void; | 点击返回按钮时触发,建议返回上一级页面。 |
/chat/demo/entry/src/main/ets/pages/HomePage.ets 作为上述 Page 的粘合层,实现了各个 Page 的回调事件,核心示例代码如下:
import { ConversationInfo, ContactInfo, MessageInfo } from '@tencentcloud/atomicxcore';// 点击会话列表 cell 跳转ConversationsPage({onConversationClick: (item: ConversationInfo) => {this.handleConversationClick(item);}})// 点击联系人页面跳转ContactsPage({onContactClick: (contact: ContactInfo) => {this.handleContactClick(contact);},onGroupClick: (group: ContactInfo) => {this.handleGroupClick(group);}})// ChatDialog 是对 ChatPage 外层封装了导航栏的页面// onUserClick 和 onChatHeaderClick 的实现会透传到 ChatPage@CustomDialogexport struct ChatDialog {controller: CustomDialogController;conversationID: string = '';title: string = '';status: string = '';avatarUrl: string = '';locateMessage?: MessageInfo = undefined;onBack?: () => void;onUserClick?: (userID: string) => void;onChatHeaderClick?: (conversationID: string) => void;build() {ChatPage({conversationID: this.conversationID,title: this.title,status: this.status,avatarUrl: this.avatarUrl,locateMessage: this.locateMessage,onBack: () => {if (this.onBack) {this.onBack();}this.controller.close();},onUserClick: (userID: string) => {this.onUserClick(userID);},onChatHeaderClick: (conversationID: string) => {this.onChatHeaderClick(conversationID);}})}}
可参考上述回调说明及参考代码,实现 Page 之间交互逻辑。
HAR 包定制集成
打包与集成方式
1. atomic_x.har 打包配置。
文件路径:
atomic_x/oh-package.json5。{"name": "@tencentcloud/atomicx",···"dependencies": {"@tencentcloud/atomicxcore": "^5.0.0","@tencentcloud/imsdk": "^9.0.7652","@tencent/mmkv": "1.3.5"}}
2. chatuikit.har 打包配置。
文件路径:
chat/uikit/oh-package.json5。{"name": "chatuikit",···"dependencies": {"@tencentcloud/atomicxcore": "^5.0.0","@tencentcloud/atomicx": "file:./atomic_x.har"}}
3. Demo 应用入口依赖配置。
文件路径:
chat/demo/entry/oh-package.json5。"dependencies": {···"@tencentcloud/atomicxcore": "^5.0.0","@tencentcloud/atomicx": "file:./atomic_x.har","chatuikit": "file:./chatuikit.har",···}
4. 打开文件
chat/demo/build-profile.json5,删除 atomic_x、chatuikit 模块,点击 File > Invalidate Caches 执行 IDE 缓存清理。5. 如果 demo 运行时资源报错
Error: Invalid resource ID: 0,是由于 HAR 集成时跨模块资源 id 映射为 0 导致,请修改 atomic_x 模块 getStringSync($r('app.string.xxx').id) → getStringByNameSync('xxx') 如下修改后,请注意按照步骤4清理缓存,重新打包集成。- getContext().resourceManager.getStringSync($r('app.string.message_type_image').id);+ getContext().resourceManager.getStringByNameSync('message_type_image');
常见问题
功能常见问题
登录失败,提示签名错误
如何移除音视频通话功能?
如果您不需要集成音视频通话功能,可按以下步骤完全移除:
移除依赖:删除
entry/oh-package.json5 中 dependencies 里的 "@tencentcloud/tuicallkit": 移除模块声明:删除
build-profile.json5 中 modules 里 tuicallkit 的条目。移除初始化代码:删除
EntryAbility 中 TUICallKit 的 attach / detach 调用,以及入口页(如 HomePage)中 TUICallKit.createInstance 与 call.startCall 事件的订阅代码。