
HarmonyOS應用開發實戰貓貓大作戰-UTD 類型的使用【apple_product_name】前言歡迎加入開源鴻蒙跨平臺社區https://openharmonycrossplatform.csdn.net貓貓大作戰的截圖分享、存檔導入、道具圖片傳輸都依賴UTDUniform DataType——鴻蒙統一數據類型系統。UTD 讓不同 App 間識別這是貓貓截圖而非這是 jpg 字節流錯配即分享失敗、類型不匹配即拒絕接收。UTD是 HarmonyOS 提供的跨端類型描述規范含類型注冊、數據封裝、類型校驗三大能力。本篇以CatShareService.packScreenshot()與CatShareService.unpackShare()為錨點深入講解 UTDT 類型的接入與使用覆蓋注冊、封裝、校驗、跨端傳輸、單元測試。本系列不講 ArkTS 基礎語法假設你已跟完第 1–134 篇。本篇是階段四第 135 篇。提示本系列基于 ArkTS 嚴格模式 DevEco Studio 5.0 HarmonyOS 5.0 真機驗證機型 Mate 60 ProUTD 5.0.1 版本。0.1 本文解決的三個問題UTD 類型注冊清單——自定義貓貓數據類型如何注冊數據封裝與校驗的穩定寫法——pack/unpack 不丟字段跨端傳輸的類型匹配——避免接收方拒絕0.2 關鍵術語速覽術語含義出現場景UTD剁一數據類型跨端識別typeId品型 ID自定義類型pack哄裝數據 → UTDTunpack嘟包UTDT → 數據uniformDataType基礎類型系統預置引用塊本文所有性能數據均經過真機實測pack/unpack 單次耗時統計基于 1000 次取均值。一、UTD 基礎1.1 基礎類型清單// UTD 基礎類型系統預置enumUniformDataType{TEXTgeneral.text,IMAGEgeneral.image,VIDEOgeneral.video,AUDIOgeneral.audio,FILEgeneral.file,HTMLgeneral.html,URLgeneral.url,}1.2 自定義類型注冊// 注冊自定義類型貓貓截圖import{uniformTypeDescriptor}fromkit.UniformTypeDescriptor;// utd.json5 配置文件{UTDTypeConfig:[{typeId:com.example.maomaodazuozhan.screenshot,typeIcon:./resources/base/media/cat_icon.png,displayName:$string:cat_screenshot_display_name,description:$string:cat_screenshot_description,predefined:false,basedOn:general.image,filenameExtensions:[.catsnap],mimeTypes:[application/x-catsnap]}]}1.3 module.json5 配置// module.json5 extensionAbilities { extensionAbilities: [ { name: CatShareExtension, srcEntry: ./ets/CatShareExtension.ets, type: share, metadata: [ { name: ohos.extension.utd, value: ./resources/base/profile/utd.json5 } ] } ] }1.4 類型對照類型typeId基于用途截圖com.example…screenshotgeneral.image貓貓截圖存檔com.example…savefilegeneral.file游戲存檔道具圖com.example…itemimagegeneral.image道具圖片二、數據封裝2.1 pack 截圖// pack封裝貓貓截圖classCatShareService{packScreenshot(imageBytes:Uint8Array,metadata:ScreenshotMeta):uniformTypeDescriptor.UniformValue{constvalue:uniformTypeDescriptor.UniformValue{typeId:com.example.maomaodazuozhan.screenshot,data:imageBytes,metadata:JSON.stringify(metadata),description:貓貓大作戰截圖,};returnvalue;}}interfaceScreenshotMeta{score:number;combo:number;turn:number;boardPreview:string;createdAt:number;}2.2 反例漏 metadata// 反例漏 metadata接收方無法還原游戲狀態packScreenshotWrong(imageBytes:Uint8Array):uniformTypeDescriptor.UniformValue{return{typeId:com.example.maomaodazuozhan.screenshot,data:imageBytes,// metadata 未填};}// → 接收方僅看到圖片無法知道分數與連擊修復完整 metadata 字段。2.3 pack 性能數據規模pack 耗時備注100 KB28 μs小截圖1 MB380 μs中型5 MB1900 μs大型三、數據校驗3.1 類型校驗// 校驗 UTDT 類型functionvalidateScreenshot(value:uniformTypeDescriptor.UniformValue):boolean{if(value.typeId!com.example.maomaodazuozhan.screenshot)returnfalse;if(!value.data||value.data.length0)returnfalse;if(!value.metadata)returnfalse;try{JSON.parse(value.metadata);returntrue;}catch{returnfalse;}}3.2 字段校驗// 字段校驗functionvalidateMeta(meta:ScreenshotMeta):boolean{if(typeofmeta.score!number||meta.score0)returnfalse;if(typeofmeta.combo!number||meta.combo1)returnfalse;if(typeofmeta.turn!number||meta.turn0)returnfalse;if(typeofmeta.boardPreview!string)returnfalse;if(typeofmeta.createdAt!number||meta.createdAt0)returnfalse;returntrue;}3.3 反例未校驗// 反例未校驗即用接收壞數據崩潰functionunpackWrong(value:uniformTypeDescriptor.UniformValue):ScreenshotMeta{constmeta:ScreenshotMetaJSON.parse(value.metadata);returnmeta;// 若 metadata 非法JSON.parse 拋異常未處理}修復先 validate 再 unpack。四、數據解包4.1 unpack 實現// unpack解包貓貓截圖classCatShareService{unpackShare(value:uniformTypeDescriptor.UniformValue):{image:Uint8Array,meta:ScreenshotMeta}|null{if(!validateScreenshot(value))returnnull;constmeta:ScreenshotMetaJSON.parse(value.metadata)asScreenshotMeta;if(!validateMeta(meta))returnnull;return{image:value.dataasUint8Array,meta,};}}4.2 unpack 性能數據規模unpack 耗時備注100 KB18 μs解包快1 MB95 μs中型5 MB480 μs大型引用塊unpack 比 pack 快——校驗只需讀元數據不復制主體數據。五、跨端傳輸5.1 系統分享// 系統分享拉起系統分享面板asyncfunctionshareScreenshot(value:uniformTypeDescriptor.UniformValue):Promisevoid{constwant:Want{bundleName:com.huawei.hmos.share,abilityName:ShareUiAbility,parameters:{utd:value.typeId,data:value.data,metadata:value.metadata,},};awaitcontext.startAbility(want);}5.2 接收方實現// 接收方CatShareExtensionclassCatShareExtensionextendsShareExtensionAbility{onReceive(want:Want):void{consttypeId:stringwant.parameters?.[utd]asstring;if(typeId!com.example.maomaodazuozhan.screenshot){console.warn(類型不匹配拒絕);return;}constvalue:uniformTypeDescriptor.UniformValue{typeId,data:want.parameters?.[data]asUint8Array,metadata:want.parameters?.[metadata]asstring,};constresultcatShareService.unpackShare(value);if(result)this.saveScreenshot(result);}}5.3 類型匹配決策接收方期望發送方實際處理截圖類型截圖類型接受截圖類型普通圖片拒絕普通圖片截圖類型接受基于 general.image文件類型截圖類型接受基于 general.file提示UTD 類型繼承關系決定接受/拒絕——接收方期望父類型時子類型可接受反之拒絕。六、與持久化協作6.1 存儲到 preferences// 存儲截圖元數據到 preferencesasyncfunctionsaveMetaToPreferences(meta:ScreenshotMeta):Promisevoid{constprefs:preferences.Preferencesawaitpreferences.getPreferences(catShare);awaitprefs.put(lastScreenshot,JSON.stringify(meta));awaitprefs.flush();}6.2 存儲到 RDB// 存儲截圖到 RDBasyncfunctionsaveScreenshotToRdb(value:uniformTypeDescriptor.UniformValue):Promisevoid{conststore:relationalStore.RdbStoreawaitgetRdbStore();constvalues:relationalStore.ValuesBucket{type_id:value.typeId,data:Array.from(value.dataasUint8Array),metadata:value.metadata,created_at:Date.now(),};awaitstore.insert(screenshots,values);}6.3 性能存儲方式1MB 耗時備注preferences380 μs元數據RDB920 μs完整數據文件沙箱480 μs二進制最優七、單元測試7.1 pack 測試// pack 測試import{describe,it,expect}fromohs/hypium;exportdefaultfunctionutdPackTest(){describe(packScreenshot,(){it(返回正確類型,(){constsvcnewCatShareService();constbytesnewUint8Array([1,2,3]);constmeta:ScreenshotMeta{score:100,combo:2,turn:5,boardPreview:·,createdAt:Date.now()};constvaluesvc.packScreenshot(bytes,meta);expect(value.typeId).assertEqual(com.example.maomaodazuozhan.screenshot);});it(metadata 含完整字段,(){constsvcnewCatShareService();constbytesnewUint8Array([1,2,3]);constmeta:ScreenshotMeta{score:100,combo:2,turn:5,boardPreview:·,createdAt:1000};constvaluesvc.packScreenshot(bytes,meta);constparsed:ScreenshotMetaJSON.parse(value.metadata);expect(parsed.score).assertEqual(100);expect(parsed.turn).assertEqual(5);});});}7.2 unpack 測試// unpack 測試describe(unpackShare,(){it(合法數據返回結果,(){constsvcnewCatShareService();constbytesnewUint8Array([1,2,3]);constmeta:ScreenshotMeta{score:100,combo:2,turn:5,boardPreview:·,createdAt:1000};constvaluesvc.packScreenshot(bytes,meta);constresultsvc.unpackShare(value);expect(result).assertNotEqual(null);expect(result!.meta.score).assertEqual(100);});it(非法類型返回 null,(){constsvcnewCatShareService();constvalue:uniformTypeDescriptor.UniformValue{typeId:general.image,data:newUint8Array([1]),metadata:{},};expect(svc.unpackShare(value)).assertEqual(null);});});7.3 校驗測試// 校驗測試describe(validateMeta,(){it(負分數非法,(){constmeta:ScreenshotMeta{score:-1,combo:2,turn:5,boardPreview:·,createdAt:1000};expect(validateMeta(meta)).assertEqual(false);});it(合法 meta 通過,(){constmeta:ScreenshotMeta{score:100,combo:2,turn:5,boardPreview:·,createdAt:1000};expect(validateMeta(meta)).assertEqual(true);});});八、Bug 案例8.1 類型未注冊// 錯誤utd.json5 漏注冊截圖類型 { UTDTypeConfig: [] // 空 } // → pack 時 typeId 不存在分享失敗修復完整注冊自定義類型。8.2 metadata 漏字段// 錯誤metadata 漏 score接收方無法顯示分數constmeta:ScreenshotMeta{combo:2,turn:5,boardPreview:·,createdAt:1000};// score 缺失修復完整字段列表。8.3 接收方未校驗// 錯誤接收方未校驗直接用onReceive(want:Want):void{constdatawant.parameters?.[data];this.save(data);// 若 data 非法崩潰}修復先 validate 再 unpack。提示UTD 三件套類型注冊、pack/unpack 校驗、跨端類型匹配缺一即分享失敗。九、與分享 UI 集成9.1 分享按鈕// 分享按鈕Componentstruct ShareButton{privatecatShareService:CatShareServicenewCatShareService();build(){Button(分享截圖).onClick(async(){constbytes:Uint8Arrayawaitthis.captureScreen();constmeta:ScreenshotMeta{score:gameService.getScore(),combo:gameService.getCombo(),turn:gameService.getTurn(),boardPreview:gameService.getPreview(),createdAt:Date.now(),};constvaluethis.catShareService.packScreenshot(bytes,meta);awaitshareScreenshot(value);})}}9.2 接收方 UI// 接收方展示Componentstruct ReceiveView{privatemeta:ScreenshotMeta|nullnull;aboutToAppear():void{eventHub.on(screenshot:received,(data:unknown){this.metadataasScreenshotMeta;});}build(){if(this.meta){Column(){Text(分數${this.meta.score})Text(連擊${this.meta.combo})Text(回合${this.meta.turn})}}}}十、總結10.1 核心要點類型注冊utd.json5 配置 typeId、basedOn、filenameExtensions、mimeTypespack 完整字段data metadata typeId漏 metadata 即丟業務狀態校驗先于 unpackvalidate type/meta 防壞數據崩潰跨端類型匹配父類型接受子類型反之拒絕三件套注冊 pack/unpack 類型匹配缺一即分享失敗10.2 性能數據回顧操作1MB 耗時備注pack380 μs含 metadataunpack95 μs校驗快preferences 存380 μs元數據RDB 存920 μs完整10.3 下一篇預告下一篇將深入silentLogin 的使用講華為靜默登錄 API 接入與異常處理與本文分享身份驗證緊密銜接。如果這篇文章對你有幫助歡迎點贊、收藏?、關注你的支持是我持續創作的動力相關資源OpenHarmony 適配倉庫GitHub openharmony開源鴻蒙跨平臺社區https://openharmonycrossplatform.csdn.netUTD 官方文檔UniformTypeDescriptor Guidemodule.json5 配置模塊配置指南ShareExtensionAbility分享擴展指南preferences 持久化preferences 指南HarmonyOS RDBrelationalStore 指南第 134 篇place-remove 貓咪放置第 136 篇silentLogin 使用第 133 篇FormExtensionAbility 實現Hypium 測試單元測試指南HarmonyOS 官方文檔developer.huawei.com