HarmonyOS Next中關鍵資產儲存操作實戰指南

SameX發表於2024-11-09

本文旨在深入探討華為鴻蒙HarmonyOS Next系統(截止目前 API12)在開發多語言電商平臺方面的技術細節,基於實際開發實踐進行總結。主要作為技術分享與交流載體,難免錯漏,歡迎各位同仁提出寶貴意見和問題,以便共同進步。本文為原創內容,任何形式的轉載必須註明出處及原作者。

(一)引言

在上一篇部落格中,我們深入瞭解了HarmonyOS Next系統中Asset Store Kit的基礎知識,包括其在關鍵資產儲存和管理方面的重要地位、關鍵資產儲存原理、訪問控制機制以及各種關鍵資產屬性等。這些基礎知識為我們進一步探索關鍵資產儲存操作奠定了堅實的基礎。在本篇部落格中,我們將深入實戰,詳細講解如何在HarmonyOS Next中進行關鍵資產的儲存操作,包括新增、查詢、更新和刪除等關鍵操作,幫助開發者更好地掌握這一重要功能。

(二)新增關鍵資產

  1. 流程和注意事項
    - 新增關鍵資產的流程主要包括準備關鍵資產屬性、呼叫新增介面以及處理可能出現的錯誤。首先,開發者需要根據業務需求確定關鍵資產的各項屬性,如密碼(SECRET)、別名(ALIAS)、訪問控制等級(ACCESSIBILITY)等。其中,密碼是必選屬性,且長度應在1 - 1024位元組之間,而別名也是必選屬性,用於唯一標識關鍵資產,其長度為1 - 256位元組。在設定屬性時,需注意屬性的合法性和合理性,例如,訪問控制等級應選擇合適的值(如開機後可訪問、首次解鎖後可訪問或解鎖時可訪問)。同時,如果需要在應用解除安裝時保留關鍵資產,可設定IS_PERSISTENT屬性為true,但需提前申請ohos.permission.STORE_PERSISTENT_DATA許可權。
    - 另外,關鍵資產以業務身份 + 別名作為唯一索引,因此必須保證每條關鍵資產的別名唯一,否則可能導致新增失敗或資料混亂。
  2. 程式碼示例(ArkTS)
import { asset } from '@kit.AssetStoreKit';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
function stringToArray(str: string): Uint8Array {
    let textEncoder = new util.TextEncoder();
    return textEncoder.encodeInto(str);
}
// 新增一個關鍵資產,包含密碼和別名等屬性
let attr: asset.AssetMap = new Map();
attr.set(asset.Tag.SECRET, stringToArray('newPassword123')); // 假設密碼為"newPassword123"
attr.set(asset.Tag.ALIAS, stringToArray('newAssetAlias')); // 設定別名為"newAssetAlias"
attr.set(asset.Tag.ACCESSIBILITY, asset.Accessibility.DEVICE_FIRST_UNLOCKED); // 設定為首次解鎖後可訪問
try {
    asset.add(attr).then(() => {
        console.info('Key asset added successfully.');
    }).catch((err: BusinessError) => {
        console.error('Failed to add key asset. Code is ${err.code}, message is ${err.message}');
    });
} catch (error) {
    let err = error as BusinessError;
    console.error('Failed to add key asset. Code is ${err.code}, message is ${err.message}');
}
  1. 程式碼示例(C/C++)
#include <string.h>
#include "asset/asset_api.h"
void AddAsset() {
    static const char *SECRET = "newPassword123";
    static const char *ALIAS = "newAssetAlias";
    Asset_Blob secret = { (uint32_t)(strlen(SECRET)), (uint8_t *)SECRET };
    Asset_Blob alias = { (uint32_t)(strlen(ALIAS)), (uint8_t *)ALIAS };
    Asset_Attr attr[] = {
        {.tag = ASSET_TAG_SECRET,.value.blob = secret },
        {.tag = ASSET_TAG_ALIAS,.value.blob = alias },
        {.tag = ASSET_TAG_ACCESSIBILITY,.value.uint32 = ASSET_ACCESSIBILITY_DEVICE_FIRST_UNLOCKED }
    };
    int32_t ret = OH_Asset_Add(attr, sizeof(attr) / sizeof(attr[0]));
    if (ret == ASSET_SUCCESS) {
        // Asset added successfully.
    } else {
        // Failed to add Asset.
    }
}

(三)查詢關鍵資產

  1. 多種查詢方式
    - 按屬性查詢:可以根據關鍵資產的各種屬性(如別名、訪問控制等級等)進行精確查詢。例如,透過指定別名來查詢特定的關鍵資產,或者根據訪問控制等級篩選出在特定鎖屏狀態下可訪問的關鍵資產。
    - 分批查詢:由於批次查詢出的關鍵資產需要透過IPC通道傳輸給業務,受IPC緩衝區大小限制,當查詢結果可能超過40條時,建議進行分批查詢,且每次查詢數量不超過40條。分批查詢可以透過設定RETURN_OFFSET和RETURN_LIMIT引數來實現,RETURN_OFFSET指定從第幾個關鍵資產開始返回,RETURN_LIMIT指定返回的關鍵資產數量。
  2. 查詢引數含義和用法
查詢引數 含義 用法示例
ALIAS(別名) 用於唯一標識關鍵資產的字串 查詢別名為"specificAlias"的關鍵資產:query.set(asset.Tag.ALIAS, stringToArray('specificAlias'));
ACCESSIBILITY(訪問控制等級) 基於鎖屏狀態的訪問控制設定 查詢首次解鎖後可訪問的關鍵資產:query.set(asset.Tag.ACCESSIBILITY, asset.Accessibility.FIRST_UNLOCKED);
RETURN_TYPE(查詢返回型別) 指定查詢返回結果的型別 查詢返回所有型別的關鍵資產:query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ALL);
RETURN_LIMIT(查詢返回數量限制) 限制查詢返回的關鍵資產數量 查詢最多返回10個關鍵資產:query.set(asset.Tag.RETURN_LIMIT, 10);
RETURN_OFFSET(查詢返回偏移量) 指定從第幾個關鍵資產開始返回 從第20個關鍵資產開始查詢,最多返回10個:query.set(asset.Tag.RETURN_OFFSET, 20);
RETURN_ORDERED_BY(查詢結果排序依據) 按照附屬資訊排序查詢結果 按照DATA_LABEL_NORMAL_1屬性排序:query.set(asset.Tag.RETURN_ORDERED_BY, asset.Tag.DATA_LABEL_NORMAL_1);
  1. 程式碼示例(根據條件查詢關鍵資產)
import { asset } from '@kit.AssetStoreKit';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
function stringToArray(str: string): Uint8Array {
    let textEncoder = new util.TextEncoder();
    return textEncoder.encodeInto(str);
}
// 查詢別名為"searchAlias"且首次解鎖後可訪問的關鍵資產
let query: asset.AssetMap = new Map();
query.set(asset.Tag.ALIAS, stringToArray('searchAlias'));
query.set(asset.Tag.ACCESSIBILITY, asset.Accessibility.FIRST_UNLOCKED);
try {
    let res: Array<asset.AssetMap> = await asset.query(query);
    for (let i = 0; i < res.length; i++) {
        // 處理查詢結果
        console.log('Found asset:', res[i]);
    }
} catch (error) {
    let err = error as BusinessError;
    console.error('Failed to query asset. Code is ${err.code}, message is ${err.message}');
}

(四)更新關鍵資產

  1. 步驟和限制
    - 更新關鍵資產的步驟包括構建查詢條件以確定要更新的關鍵資產,然後設定要更新的屬性值,最後呼叫更新介面。需要注意的是,更新操作只能更新部分屬性,如關鍵資產明文(SECRET)、普通附屬資訊(DATA_LABEL_NORMAL_1 - 4等),而對於具有完整性保護的屬性(如DATA_LABEL_CRITICAL_1 - 4),寫入後不支援更新。同時,查詢條件中的別名(ALIAS)是必選屬性,用於準確找到要更新的關鍵資產。
  2. 程式碼示例(更新關鍵資產屬性)
import { asset } from '@kit.AssetStoreKit';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
function stringToArray(str: string): Uint8Array {
    let textEncoder = new util.TextEncoder();
    return textEncoder.encodeInto(str);
}
let query: asset.AssetMap = new Map();
query.set(asset.Tag.ALIAS, stringToArray('updateAlias')); // 根據別名找到要更新的關鍵資產
let attrsToUpdate: asset.AssetMap = new Map();
attrsToUpdate.set(asset.Tag.SECRET, stringToArray('newUpdatedPassword')); // 更新密碼
attrsToUpdate.set(asset.Tag.DATA_LABEL_NORMAL_1, stringToArray('newUpdatedInfo')); // 更新普通附屬資訊
try {
    asset.update(query, attrsToUpdate).then(() => {
        console.info('Key asset updated successfully.');
    }).catch((err: BusinessError) => {
        console.error('Failed to update key asset. Code is ${err.code}, message is ${err.message}');
    });
} catch (error) {
    let err = error as BusinessError;
    console.error('Failed to update key asset. Code is ${err.code}, message is ${err.message}');
}

(五)刪除關鍵資產

  1. 方法和注意點
    - 刪除關鍵資產可以透過指定關鍵資產的屬性(如別名)來確定要刪除的目標。如果不指定別名,則會刪除多條符合其他條件(如果有設定)的關鍵資產。在執行刪除操作時,需要謹慎操作,確保刪除的是正確的關鍵資產,因為一旦刪除,資料將無法恢復。
  2. 程式碼示例(刪除指定關鍵資產)
import { asset } from '@kit.AssetStoreKit';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
function stringToArray(str: string): Uint8Array {
    let textEncoder = new util.TextEncoder();
    return textEncoder.encodeInto(str);
}
let query: asset.AssetMap = new Map();
query.set(asset.Tag.ALIAS, stringToArray('deleteAlias')); // 指定要刪除的關鍵資產的別名
try {
    asset.remove(query).then(() => {
        console.info('Key asset deleted successfully.');
    }).catch((err: BusinessError) => {
        console.error('Failed to delete key asset. Code is ${err.code}, message is ${err.message}');
    });
} catch (error) {
    let err = error as BusinessError;
    console.error('Failed to delete key asset. Code is ${err.code}, message is ${err.message}');
}

(六)總結與實踐建議

  1. 關鍵資產儲存操作要點總結
    - 新增關鍵資產時要確保屬性設定正確且別名唯一,注意密碼長度和許可權要求。查詢關鍵資產時要根據需求選擇合適的查詢方式和引數,合理利用分批查詢避免IPC緩衝區問題。更新關鍵資產時需明確可更新的屬性範圍,透過別名準確定位要更新的資產。刪除關鍵資產時要謹慎確認刪除目標,避免誤刪重要資料。
  2. 實際應用建議
    - 在實際應用開發中,首先要根據業務場景規劃好關鍵資產的結構和屬性設定。例如,對於高安全性需求的金融類應用,應嚴格設定訪問控制等級和密碼策略,定期更新密碼等關鍵資產。在進行查詢操作時,儘量最佳化查詢條件,減少不必要的查詢開銷,提高效能。對於更新和刪除操作,要做好資料備份和日誌記錄,以便在出現問題時能夠追溯和恢復資料。同時,要密切關注HarmonyOS Next系統的更新和最佳化,及時調整應用中的關鍵資產儲存操作,以適應新的系統特性和安全要求。

相關文章