HarmonyOS 實踐之應用狀態變數共享

HarmonyOS開發者社群發表於2023-12-27

平時在開發的過程中,我們會在應用中|共享資料,在不同的頁面間共享資訊。雖然常用的共享資訊,也可以透過不同頁面中元件間資訊共享的方式,但有時使用應用級別的狀態管理會讓開發工作變得簡單。


根據不同的使用場景, ArkTS 提供了以下幾種應用狀態管理的能力:

○  LocalStorage :使用範圍在同一頁面,頁面與卡片和頁面與 UIAbility 內部,負責 UI 狀態儲存。

○  AppStorage:執行時儲存,儲存在記憶體中,應用範圍全域性共享,提供統一的儲存供所有頁面訪問。

○  PersistentStorage:持久化儲存,儲存在硬碟上,在應用退出或重啟後,資料依舊保留。


下面透過簡單的程式示例,熟悉一下這三種用法。其中示例程式中包含了以下主要檔案:


HarmonyOS 實踐之應用狀態變數共享


一、LocalStorage

頁面級的 UI 狀態儲存,同一個頁面共享同一個 LocalStorage,不同的頁面都可以繫結對應的 LocalStorage。最常用的就是更新服務卡片和跨頁面的資訊傳遞。

場景一:更新服務卡片

服務卡片中被 @Entry 裝飾的 @Component,可以被分配一個 LocalStorage 例項,在元件內部,透過 @LocalStorageProp 裝飾器定義本地變數,並繫結到對應元件上。更新卡片時,先定義一個包含了和 LocalStorageProp 屬性同名的引數並放到 formBindingData 中,然後透過 formProvider.updateForm 函式,就可以更新服務卡片了。

我們要在 EntryFormAbility.ets 中透過傳遞 LocalStorage 改變服務卡片中的預設 Hello 的文字標籤為當前時間。

實踐步驟:

1.修改服務卡片佈局檔案,檔案開頭新增:



let storage = 
new 
LocalStorage();




併為 Entry 增加引數 storage。

例如,WidgetCard.ets,預設:



@Entry

@Component

struct 
WidgetCard {

...




改之後:



let 
storage 
= 
new 
LocalStorage();

@Entry(storage)

@Component
struct WidgetCard {
...




2.在 EntryFormAbility.ets 中,用裝飾器 LocalStorageProp 定義本地變數,裝飾器的引數必須要和 formBindingData 中的屬性名稱相同。

例如,在接收方服務卡片中定義如下:



@LocalStorageProp(
'localprop') localValue: string = 
'Hello';




HarmonyOS 實踐之應用狀態變數共享


卡片標籤預設顯示了 Hello。

在傳送方 EntryFormAbility. ts 檔案 的 onFormEvent 函式里:



onFormEvent(
formId, message) {
  
let date = 
new 
Date();
  
let str = date.
getHours().
toString().
padStart(
2'0') + 
':' +  date.
getMinutes().
toString().
padStart(
2'0') + 
':' + date.
getSeconds().
toString().
padStart(
2'0')
  
let formData = {
    
'localprop''Time: ' + str,
  };
  
let formInfo = formBindingData.
createFormBindingData(formData)
  formProvider.
updateForm(formId, formInfo).
then(
(
data) => {
    
console.
info(
'FormAbility updateForm success.' + 
JSON.
stringify(data));
  }).
catch(
(
error) => {
    
console.
error(
'FormAbility updateForm failed: ' + 
JSON.
stringify(error));
  })
}




formData 物件裡包含了名稱為 localprop 的鍵值,它透過 formBindingData 由 formProvider 傳遞給服務卡片,服務卡片接收到該物件後,就自動把該物件賦值給 LocalStorage,相應的 LocalStorageProp 也自動跟著重新整理。

這個動作是透過點選卡片上的 update 按鈕,觸發了 postCardAction 事件從而呼叫了 onFormEvent 函式,執行結果如下:


HarmonyOS 實踐之應用狀態變數共享


場景二:跨頁面的資訊傳遞

在頁面初次載入時,可以在 EntryAbility.ts 中傳遞一個 LocalStorage 物件給要開啟的頁面。

我們打算在 index.ets 頁面載入的時候,在 EntryAbility 中傳遞一個包含 abilitycount 值為 1 的 Storage,頁面載入後介面顯示該值。

實踐步驟:

1.在 EntryAbility.ts 中定義一個 LocalStorage 型別的變數,裡面包含 abilitycount 屬性。



export 
default 
class 
EntryAbility 
extends 
UIAbility {
  
storageLocalStorage = 
new 
LocalStorage({
    
'abilitycount'1
  });




在 onWindowStageCreate 函式中,將預設的:


windowStage.
loadContent(
'pages/Index'(
err, data) => {




改為傳遞引數的方式,如下:


windowStage.loadContent(
'pages/Index'this.storage);




2.在頁面端 Index.ets 中,檔案開頭新增程式碼來獲取共享的 LocalStorage。



let storage = 
LocalStorage.
GetShared()




在結構體內部,透過裝飾器 LocalStorageProp 加同樣屬性名稱作為引數,定義一個變數。



@LocalStorageProp(
'abilitycount') abilityCount: number = 
0;




這樣名為 abilitycount 的值就透過 LocalStorage 傳遞到頁面了,本地預設的值 0 變為了傳遞過來的值 1。

下圖中 LocalStorage 的值就是頁面開啟時顯示的傳遞過來的值。


HarmonyOS 實踐之應用狀態變數共享


二、AppStorage

全域性的 UI 狀態儲存,在執行時階段可以在不同的頁面間共享資訊。我們透過在 Index.ets 頁面建立一個變數放到 AppStorage 中,然後分別在 First.ets 頁面和 Second.ets 頁面訪問和修改。

實踐步驟:

1.首先在 Index.ets 中,透過 AppStorage 定義一個屬性。



AppStorage.
SetOrCreate(
'appcount'10);




然後,在元件結構體中使用 StorageProp 裝飾器定義一個變數,引數為之前定義的 appcount 屬性。



@Entry()

@Component
struct Index {



   @StorageProp( 'appcount') appValue: number =  0;



2.在 First.ets 頁面中,透過 StorageProp 定義一個 appValue 變數,關聯到 appcount 屬性上。


struct First {
  
@StorageProp(
'appcount') appValue: number = 
0;




在本地修改時,把使用者輸入的值寫入 AppStorage,使用如下語句:



AppStorage.
Set(
'appcount'this.
textApp);




Second.ets 頁面與 First.ets 頁面功能完全相同,主要顯示 AppStorage 在不同頁面顯示和修改的效果。

如下圖,主頁面、第一個頁面和第二個頁面初始狀態下,讀取到的 AppStorage 中的同一個屬性的值都是 10。


HarmonyOS 實踐之應用狀態變數共享

在第一個頁面 First.ets 中把 AppStorage 中的屬性值改為 11,我們發現在主頁面 Index.ets 和 Second.ets 中,對應的屬性值都發生了變化。


HarmonyOS 實踐之應用狀態變數共享

同樣,在第二個頁面 Second.ets 中把 AppStorage 中的屬性值改為 12,我們發現在 Index.ets 和 First.ets 中,對應的屬性值也都變為了改後的值。


HarmonyOS 實踐之應用狀態變數共享

如上測試,我們發現的確可以透過 AppStorage 在不同頁面間共享資料。

三、PersistentStorage

持久化儲存 UI 狀態。儲存在 PersistentStorage 中的資料,即使應用退出了,對應的值依然會保留,不是在記憶體中,而是儲存在固定儲存介質上的。

我們透過在 Index.ets 頁面建立一個屬性放到 PersistentStorage 中,然後分別在 First.ets 頁面和 Second.ets 頁面進行修改,然後再重啟應用觀察結果。

實踐步驟:

1.首先在 Index.ets 中,在 PersistentStorage 裡定義一個屬性。



PersistentStorage.
PersistProp(
'persistentcount'100);



然後在元件結構體中,透過裝飾器 StorageProp 定義一個屬性為 persistentcount 的變數。



@Entry()

@Component
struct Index {
  
@StorageProp(
'persistentcount') persistentValue: number = 
0;




2.在 First.ets 頁面中,我們透過裝飾器 StorageProp 定義一個 變數繫結 persistentcount 屬性。



@Entry

@Component
struct First {
  
@StorageProp(
'persistentcount') persistentValue: number = 
0;




透過輸入框輸入新值改變原來儲存在 PersistentStorage 的內容。



AppStorage.
Set(
'persistentcount'this.
textPersistent);




演示效果如下圖,Index.ets 頁面,在初始時 AppStorage 和 PersistentStorage 中的對應屬性值分別是 10 和 100,在 First.ets 頁面中,我們分別改為 11 和 111。


HarmonyOS 實踐之應用狀態變數共享

關閉應用,然後重新開啟,如下圖所示,AppStorage 中的屬性值恢復為了 10,PersistentStorage 中的屬性值依舊是 111,是改後的值。這證明了 PersistentStorage 有持續化儲存的作用。


HarmonyOS 實踐之應用狀態變數共享


四、總結

透過這次實踐,熟悉了不同的狀態變數在應用中的不同應用範圍,選用合適的狀態變數會讓應用開發簡單快捷,本地頁面內部使用 LocalStorage 儲存資料,應用頁面間透過 AppStorage 傳遞資訊,PersistentStorage 可以持久化儲存資料資訊。


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70009402/viewspace-3001735/,如需轉載,請註明出處,否則將追究法律責任。

相關文章