應用級變量的狀態管理
在前面的章節中,已經講述了如何管理頁面級變量的狀態,本章將說明如何管理應用級變量的狀態,具體接口說明請參考應用級變量的狀態管理接口。
AppStorage
AppStorage是應用程序中的單例對象,由UI框架在應用程序啟動時創建,在應用程序退出時銷毀,為應用程序范圍內的可變狀態屬性提供中央存儲。
AppStorage包含整個應用程序中需要訪問的所有狀態屬性,只要應用程序保持運行,AppStorage就會保存所有屬性及屬性值,屬性值可以通過唯一的鍵值進行訪問。
組件可以通過裝飾器將應用程序狀態數據與AppStorage進行同步,應用業務邏輯的實現也可以通過接口訪問AppStorage。
AppStorage的選擇狀態屬性可以與不同的數據源或數據接收器同步,這些數據源和接收器可以是設備上的本地或遠程,并具有不同的功能,如數據持久性。這樣的數據源和接收器可以獨立于UI在業務邏輯中實現。
默認情況下,AppStorage中的屬性是可變的,AppStorage還可使用不可變(只讀)屬性。
說明:Worker和主線程只能通過postMessage交互,不能使用AppStorage進行交互。
@StorageLink裝飾器
組件通過使用@StorageLink(key)裝飾的狀態變量,與AppStorage建立雙向數據綁定,key為AppStorage中的屬性鍵值。當創建包含@StorageLink的狀態變量的組件時,該狀態變量的值將使用AppStorage中的值進行初始化。在UI組件中對@StorageLink的狀態變量所做的更改將同步到AppStorage,并從AppStorage同步到任何其他綁定實例中,如PersistentStorage或其他綁定的UI組件。
@StorageProp裝飾器
組件通過使用@StorageProp(key)裝飾的狀態變量,與AppStorage建立單向數據綁定,key標識AppStorage中的屬性鍵值。當創建包含@StorageProp的狀態變量的組件時,該狀態變量的值將使用AppStorage中的值進行初始化。AppStorage中屬性值的更改會導致綁定該狀態變量的UI組件進行狀態更新。
示例
每次用戶單擊Count按鈕時,this.varA變量值都會增加1,此變量與AppStorage中的varA同步。每次用戶單擊language按鈕時,修改AppStorage中的languageCode,此修改會同步給this.languageCode變量。
// xxx.ets
@Entry
@Component
struct ComponentA {
@StorageLink('varA') varA: number = 2
@StorageProp('languageCode') languageCode: string = 'en'
private label: string = 'count'
aboutToAppear() {
this.label = (this.languageCode === 'zh') ? '數量' : 'Count'
}
build() {
Column() {
Row({ space: 20 }) {
Button(`${this.label}: ${this.varA}`)
.onClick(() = > {
AppStorage.Set< number >('varA', AppStorage.Get< number >('varA') + 1)
})
Button(`language: ${this.languageCode}`)
.onClick(() = > {
if (AppStorage.Get< string >('languageCode') === 'zh') {
AppStorage.Set< string >('languageCode', 'en')
} else {
AppStorage.Set< string >('languageCode', 'zh')
}
this.label = (this.languageCode === 'zh') ? '數量' : 'Count'
})
}
.margin({ top: 50, bottom: 50 })
Row() {
Button(`更改@StorageLink修飾的變量:${this.varA}`).height(40).fontSize(14)
.onClick(() = > {
this.varA++
})
}
}.width('100%')
}
}
LocalStorage
說明:
該接口從API version 9開始支持。后續版本如有新增內容,則采用上角標單獨標記該內容的起始版本。
LocalStorage是應用程序中的存儲單元,生命周期跟隨其關聯的Ability。在Stage模型下,LocalStorage解決AppStorage共享范圍過大的問題,提供Ability之間全局數據的隔離。同時,LocalStorage為應用程序范圍內的可變狀態屬性和非可變狀態屬性提供存儲,可變狀態屬性和非可變狀態屬性是構建應用程序UI的一部分,如一個Ability的UI。解決App與Ability之間數據互相干擾問題,多實例場景下同一個Ability類的不同Ability實例之間的數據互相干擾問題。在分布式遷移的場景下,Ability是系統調度的最小單元,配合LocalStorage更方便實現組件的數據遷移。
應用層:一個應用程序可以創建多個LocalStorage實例,應用程序的每一個Ability對應一個LocalStorage實例。
Ability:一個應用程序可以擁有多個Ability,一個Ability中的所有子組件最多可以分配一個LocalStorage實例。并且,Ability中的所有子組件都將繼承對此LocalStorage實例存儲對象的訪問權。
一個組件最多可以訪問一個LocalStorage實例,一個LocalStorage對象可以分配給多個組件。
@LocalStorageLink裝飾器
組件通過使用@LocalStorageLink(key)裝飾的狀態變量,key值為LocalStorage中的屬性鍵值,與LocalStorage建立雙向數據綁定。當創建包含@LocalStorageLink的狀態變量的組件時,該狀態變量的值將會使用LocalStorage中的值進行初始化。如果LocalStorage中未定義初始值,將使用@LocalStorageLink定義的初始值。在UI組件中對@LocalStorageLink的狀態變量所做的更改將同步到LocalStorage中,并從LocalStorage同步到Ability下的組件中。
@LocalStorageProp裝飾器
組件通過使用LocalStorageProp(key)裝飾的狀態變量,key值為LocalStorage中的屬性鍵值,與LocalStorage建立單向數據綁定。當創建包含@LocalStorageProp的狀態變量的組件時,該狀態變量的值將使用LocalStorage中的值進行初始化。LocalStorage中的屬性值的更改會導致當前Ability下的所有UI組件進行狀態更新。
說明:創建LocalStorage實例時如未定義初始值,可以使用組件內@LocalStorageLink和@LocalStorageProp的初始值。如果定義時給定了初始值,那么不會再使用@LocalStorageLink和@LocalStorageProp的初始值。
示例1(在一個Ability中創建LocalStorage)
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
storage: LocalStorage
onCreate() {
this.storage = new LocalStorage()
this.storage.setOrCreate('storageSimpleProp', 121)
console.info('[Demo EntryAbility onCreate]')
}
onDestroy() {
console.info('[Demo EntryAbility onDestroy]')
}
onWindowStageCreate(windowStage) {
// storage作為參數傳遞給loadContent接口
windowStage.loadContent('pages/Index', this.storage)
}
onWindowStageDestroy() {
console.info('[Demo] EntryAbility onWindowStageDestroy')
}
onForeground() {
console.info('[Demo] EntryAbility onForeground')
}
onBackground() {
console.info('[Demo] EntryAbility onBackground')
}
}
@Component組件獲取數據
// Index.ets
let storage = LocalStorage.GetShared()
@Entry(storage)
@Component
struct LocalStorageComponent {
@LocalStorageLink('storageSimpleProp') simpleVarName: number = 0
build() {
Column() {
Button(`LocalStorageLink: ${this.simpleVarName.toString()}`)
.margin(20)
.onClick(() = > {
this.simpleVarName += 1
})
Text(JSON.stringify(this.simpleVarName))
.fontSize(50)
LocalStorageComponentProp()
}.width('100%')
}
}
@Component
struct LocalStorageComponentProp {
@LocalStorageProp('storageSimpleProp') simpleVarName: number = 0
build() {
Column() {
Button(`LocalStorageProp: ${this.simpleVarName.toString()}`)
.margin(20)
.onClick(() = > {
this.simpleVarName += 1
})
Text(JSON.stringify(this.simpleVarName))
.fontSize(50)
}.width('100%')
}
}
示例2(在Entry頁面定義LocalStorage)
// xxx.ets
let storage = new LocalStorage({ "PropA": 47 })
@Entry(storage)
@Component
struct ComA {
@LocalStorageLink("PropA") storageLink: number = 1
build() {
Column() {
Text(`Parent from LocalStorage ${this.storageLink}`)
.fontSize(18)
.margin(20)
.onClick(() = > this.storageLink += 1)
Child()
}
}
}
@Component
struct Child {
@LocalStorageLink("PropA") storageLink: number = 1
build() {
Text(`Child from LocalStorage ${this.storageLink}`)
.fontSize(18)
.margin(20)
.onClick(() = > this.storageLink += 1)
}
}
PersistentStorage
PersistentStorage提供了一些靜態方法用來管理應用持久化數據,可以將特定標記的持久化數據鏈接到AppStorage中,并由AppStorage接口訪問對應持久化數據,或者通過@StorageLink裝飾器來訪問對應key的變量。
說明:
- PersistentStorage的PersistProp接口使用時,需要保證輸入對應的key在AppStorage中存在。
- PersistentStorage的DeleteProp接口使用時,只能對本次應用啟動時已經link過的數據生效。
// xxx.ets
PersistentStorage.PersistProp('highScore', '0')
@Entry
@Component
struct PersistentComponent {
@StorageLink('highScore') highScore: string = '0'
@State currentScore: number = 0
build() {
Column() {
if (this.currentScore === Number(this.highScore)) {
Text(`new highScore : ${this.highScore}`).fontSize(18)
}
Button(`goal!, currentScore : ${this.currentScore}`)
.margin(20)
.onClick(() = > {
this.currentScore++
if (this.currentScore > Number(this.highScore)) {
this.highScore = this.currentScore.toString()
}
})
}.width('100%')
}
}
Environment
Environment是框架在應用程序啟動時創建的單例對象,它為AppStorage提供了一系列應用程序需要的環境狀態數據,這些數據描述了應用程序運行的設備環境,包括系統語言、深淺色模式等等。Environment及其屬性是不可變的,所有數據類型均為簡單類型。如下示例展示了從Environment獲取系統是否開啟無障礙屏幕朗讀:
Environment.EnvProp('accessibilityEnabled', 'default')
var enable = AppStorage.Get('accessibilityEnabled')
accessibilityEnabled是Environment提供的系統默認變量識別符。首先需要將對應系統屬性綁定到AppStorage上,再通過AppStorage中的方法或者裝飾器訪問對應的系統屬性數據。
審核編輯 黃宇
-
變量
+關注
關注
0文章
607瀏覽量
28257 -
Harmony
+關注
關注
0文章
51瀏覽量
2556
發布評論請先 登錄
相關推薦
評論