應(yīng)用級(jí)變量的狀態(tài)管理
在前面的章節(jié)中,已經(jīng)講述了如何管理頁(yè)面級(jí)變量的狀態(tài),本章將說(shuō)明如何管理應(yīng)用級(jí)變量的狀態(tài),具體接口說(shuō)明請(qǐng)參考應(yīng)用級(jí)變量的狀態(tài)管理接口。
AppStorage
AppStorage是應(yīng)用程序中的單例對(duì)象,由UI框架在應(yīng)用程序啟動(dòng)時(shí)創(chuàng)建,在應(yīng)用程序退出時(shí)銷毀,為應(yīng)用程序范圍內(nèi)的可變狀態(tài)屬性提供中央存儲(chǔ)。
AppStorage包含整個(gè)應(yīng)用程序中需要訪問(wèn)的所有狀態(tài)屬性,只要應(yīng)用程序保持運(yùn)行,AppStorage就會(huì)保存所有屬性及屬性值,屬性值可以通過(guò)唯一的鍵值進(jìn)行訪問(wèn)。
組件可以通過(guò)裝飾器將應(yīng)用程序狀態(tài)數(shù)據(jù)與AppStorage進(jìn)行同步,應(yīng)用業(yè)務(wù)邏輯的實(shí)現(xiàn)也可以通過(guò)接口訪問(wèn)AppStorage。
AppStorage的選擇狀態(tài)屬性可以與不同的數(shù)據(jù)源或數(shù)據(jù)接收器同步,這些數(shù)據(jù)源和接收器可以是設(shè)備上的本地或遠(yuǎn)程,并具有不同的功能,如數(shù)據(jù)持久性。這樣的數(shù)據(jù)源和接收器可以獨(dú)立于UI在業(yè)務(wù)邏輯中實(shí)現(xiàn)。
默認(rèn)情況下,AppStorage中的屬性是可變的,AppStorage還可使用不可變(只讀)屬性。
說(shuō)明:Worker和主線程只能通過(guò)postMessage交互,不能使用AppStorage進(jìn)行交互。
@StorageLink裝飾器
組件通過(guò)使用@StorageLink(key)裝飾的狀態(tài)變量,與AppStorage建立雙向數(shù)據(jù)綁定,key為AppStorage中的屬性鍵值。當(dāng)創(chuàng)建包含@StorageLink的狀態(tài)變量的組件時(shí),該狀態(tài)變量的值將使用AppStorage中的值進(jìn)行初始化。在UI組件中對(duì)@StorageLink的狀態(tài)變量所做的更改將同步到AppStorage,并從AppStorage同步到任何其他綁定實(shí)例中,如PersistentStorage或其他綁定的UI組件。
@StorageProp裝飾器
組件通過(guò)使用@StorageProp(key)裝飾的狀態(tài)變量,與AppStorage建立單向數(shù)據(jù)綁定,key標(biāo)識(shí)AppStorage中的屬性鍵值。當(dāng)創(chuàng)建包含@StorageProp的狀態(tài)變量的組件時(shí),該狀態(tài)變量的值將使用AppStorage中的值進(jìn)行初始化。AppStorage中屬性值的更改會(huì)導(dǎo)致綁定該狀態(tài)變量的UI組件進(jìn)行狀態(tài)更新。
示例
每次用戶單擊Count按鈕時(shí),this.varA變量值都會(huì)增加1,此變量與AppStorage中的varA同步。每次用戶單擊language按鈕時(shí),修改AppStorage中的languageCode,此修改會(huì)同步給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') ? '數(shù)量' : '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') ? '數(shù)量' : 'Count'
})
}
.margin({ top: 50, bottom: 50 })
Row() {
Button(`更改@StorageLink修飾的變量:${this.varA}`).height(40).fontSize(14)
.onClick(() = > {
this.varA++
})
}
}.width('100%')
}
}
LocalStorage
說(shuō)明:
該接口從API version 9開(kāi)始支持。后續(xù)版本如有新增內(nèi)容,則采用上角標(biāo)單獨(dú)標(biāo)記該內(nèi)容的起始版本。
LocalStorage是應(yīng)用程序中的存儲(chǔ)單元,生命周期跟隨其關(guān)聯(lián)的Ability。在Stage模型下,LocalStorage解決AppStorage共享范圍過(guò)大的問(wèn)題,提供Ability之間全局?jǐn)?shù)據(jù)的隔離。同時(shí),LocalStorage為應(yīng)用程序范圍內(nèi)的可變狀態(tài)屬性和非可變狀態(tài)屬性提供存儲(chǔ),可變狀態(tài)屬性和非可變狀態(tài)屬性是構(gòu)建應(yīng)用程序UI的一部分,如一個(gè)Ability的UI。解決App與Ability之間數(shù)據(jù)互相干擾問(wèn)題,多實(shí)例場(chǎng)景下同一個(gè)Ability類的不同Ability實(shí)例之間的數(shù)據(jù)互相干擾問(wèn)題。在分布式遷移的場(chǎng)景下,Ability是系統(tǒng)調(diào)度的最小單元,配合LocalStorage更方便實(shí)現(xiàn)組件的數(shù)據(jù)遷移。
應(yīng)用層:一個(gè)應(yīng)用程序可以創(chuàng)建多個(gè)LocalStorage實(shí)例,應(yīng)用程序的每一個(gè)Ability對(duì)應(yīng)一個(gè)LocalStorage實(shí)例。
Ability:一個(gè)應(yīng)用程序可以擁有多個(gè)Ability,一個(gè)Ability中的所有子組件最多可以分配一個(gè)LocalStorage實(shí)例。并且,Ability中的所有子組件都將繼承對(duì)此LocalStorage實(shí)例存儲(chǔ)對(duì)象的訪問(wèn)權(quán)。
一個(gè)組件最多可以訪問(wèn)一個(gè)LocalStorage實(shí)例,一個(gè)LocalStorage對(duì)象可以分配給多個(gè)組件。
@LocalStorageLink裝飾器
組件通過(guò)使用@LocalStorageLink(key)裝飾的狀態(tài)變量,key值為L(zhǎng)ocalStorage中的屬性鍵值,與LocalStorage建立雙向數(shù)據(jù)綁定。當(dāng)創(chuàng)建包含@LocalStorageLink的狀態(tài)變量的組件時(shí),該狀態(tài)變量的值將會(huì)使用LocalStorage中的值進(jìn)行初始化。如果LocalStorage中未定義初始值,將使用@LocalStorageLink定義的初始值。在UI組件中對(duì)@LocalStorageLink的狀態(tài)變量所做的更改將同步到LocalStorage中,并從LocalStorage同步到Ability下的組件中。
@LocalStorageProp裝飾器
組件通過(guò)使用LocalStorageProp(key)裝飾的狀態(tài)變量,key值為L(zhǎng)ocalStorage中的屬性鍵值,與LocalStorage建立單向數(shù)據(jù)綁定。當(dāng)創(chuàng)建包含@LocalStorageProp的狀態(tài)變量的組件時(shí),該狀態(tài)變量的值將使用LocalStorage中的值進(jìn)行初始化。LocalStorage中的屬性值的更改會(huì)導(dǎo)致當(dāng)前Ability下的所有UI組件進(jìn)行狀態(tài)更新。
說(shuō)明:創(chuàng)建LocalStorage實(shí)例時(shí)如未定義初始值,可以使用組件內(nèi)@LocalStorageLink和@LocalStorageProp的初始值。如果定義時(shí)給定了初始值,那么不會(huì)再使用@LocalStorageLink和@LocalStorageProp的初始值。
示例1(在一個(gè)Ability中創(chuàng)建LocalStorage)
LocalStorage通過(guò)loadContent接口加載
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作為參數(shù)傳遞給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組件獲取數(shù)據(jù)
// 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頁(yè)面定義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提供了一些靜態(tài)方法用來(lái)管理應(yīng)用持久化數(shù)據(jù),可以將特定標(biāo)記的持久化數(shù)據(jù)鏈接到AppStorage中,并由AppStorage接口訪問(wèn)對(duì)應(yīng)持久化數(shù)據(jù),或者通過(guò)@StorageLink裝飾器來(lái)訪問(wèn)對(duì)應(yīng)key的變量。
說(shuō)明:
- PersistentStorage的PersistProp接口使用時(shí),需要保證輸入對(duì)應(yīng)的key在AppStorage中存在。
- PersistentStorage的DeleteProp接口使用時(shí),只能對(duì)本次應(yīng)用啟動(dòng)時(shí)已經(jīng)link過(guò)的數(shù)據(jù)生效。
// 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是框架在應(yīng)用程序啟動(dòng)時(shí)創(chuàng)建的單例對(duì)象,它為AppStorage提供了一系列應(yīng)用程序需要的環(huán)境狀態(tài)數(shù)據(jù),這些數(shù)據(jù)描述了應(yīng)用程序運(yùn)行的設(shè)備環(huán)境,包括系統(tǒng)語(yǔ)言、深淺色模式等等。Environment及其屬性是不可變的,所有數(shù)據(jù)類型均為簡(jiǎn)單類型。如下示例展示了從Environment獲取系統(tǒng)是否開(kāi)啟無(wú)障礙屏幕朗讀:
Environment.EnvProp('accessibilityEnabled', 'default')
var enable = AppStorage.Get('accessibilityEnabled')
accessibilityEnabled是Environment提供的系統(tǒng)默認(rèn)變量識(shí)別符。首先需要將對(duì)應(yīng)系統(tǒng)屬性綁定到AppStorage上,再通過(guò)AppStorage中的方法或者裝飾器訪問(wèn)對(duì)應(yīng)的系統(tǒng)屬性數(shù)據(jù)。
審核編輯 黃宇
-
變量
+關(guān)注
關(guān)注
0文章
613瀏覽量
28369 -
Harmony
+關(guān)注
關(guān)注
0文章
53瀏覽量
2609
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論