使用用戶首選項存儲、獲取、刪除數據—OpenHarmony數據管理
用戶首選項的基本能使用
場景說明
用戶首選項為應用提供Key-Value鍵值型的數據處理能力,支持應用持久化輕量級數據,并對其修改和查詢。當用戶希望有一個全局唯一存儲的地方,可以采用用戶首選項來進行存儲。Preferences會將該數據緩存在內存中,當用戶讀取的時候,能夠快速從內存中獲取數據。Preferences會隨著存放的數據量越多而導致應用占用的內存越大,因此,Preferences不適合存放過多的數據,適用的場景一般為應用保存用戶的個性化設置(屏幕亮度,是否開啟夜間模式)等。
本例以一個小示例為大家介紹如何使用用戶首選項對數據進行存儲、獲取、刪除。
效果呈現
本例最終效果如下:
使用用戶首選項存儲、獲取、刪除數據(OpenHarmony數據管理)-開源基礎軟件社區
運行環境
本例基于以下環境開發,開發者也可以基于其他適配的版本進行開發:
- IDE: DevEco Studio 4.0 Beta1
- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
實現思路
本例以設置屏幕亮度為例演示如何使用用戶首選項管理數據,主要特性及實現方式如下:
- 當用戶在文本框輸入數據后,點擊保存數據,用戶首選項將數據緩存在內存中:通過dataPreferences類的getPreferences方法獲取用戶首選項實例,然后通過該實例調用put方法將數據寫入內存。
- 當用戶點擊讀取數據時,用戶首選項將數據從內存中讀取出來并顯示在輸入框中:通過用戶首選項實例調用get方法獲取到保存的數據,顯示在輸入框中。
- 當用戶點擊刪除數據時,用戶首選項將數據從內存中刪除,用戶無法繼續讀取數據:通過用戶首選項實例調用delete方法刪除保存的數據。
說明:
用戶首選項的使用需要注意以下幾點:
- Key鍵為string類型,要求非空且長度不超過80個字節。
- 如果Value值為string類型,請使用UTF-8編碼格式,可以為空,不為空時長度不超過8192個字節。
- 內存會隨著存儲數據量的增大而增大,所以存儲的數據量應該是輕量級的,建議存儲的數據不超過一萬條,否則會在內存方面產生較大的開銷。
開發步驟
由于本例重點講解用戶首選項的數據管理操作,所以開發步驟會著重講解如何通過用戶首選項完成數據的存儲、讀取和刪除,全量代碼可參考完整代碼章節。
首先自定義一個用戶首選項類,根據業務封裝相關方法方便后續調用。
其中包含數據處理的方法,用于完成數據的存儲、讀取和刪除操作。用戶首選項接口的使用方式主要在這部分呈現,需要重點關注。
具體代碼如下:
import dataPreferences from '@ohos.data.preferences';
import promptAction from '@ohos.promptAction';
import ScreenBrightness from '../common/bean/Brightness';
let context = getContext(this);
let preference: dataPreferences.Preferences = null;
// 自定義用戶首選項類
class PreferenceModel {
private brightness:ScreenBrightness
// 創建用戶首選項實例preference
async getPreferencesFromStorage() {
try {
preference = await dataPreferences.getPreferences(context, 'setting.db');
} catch (err) {
Logger.error('[PreferenceModel]', `Failed to get preferences, Cause: ${err}`);
}
}
// 刪除數據,調用dataPreferences的deletePreferences接口
async deletePreferences() {
try {
await dataPreferences.deletePreferences(context, 'setting.db');
} catch(err) {
Logger.error('[PreferenceModel]', `Failed to delete preferences, Cause: ${err}`);
};
preference = null;
this.showToastMessage($r('app.string.delete_success_msg'));
}
// 保存數據
async putPreference(screenBrightness:ScreenBrightness) {
if (preference === null) {
await this.getPreferencesFromStorage();
}
// 將用戶輸入的亮度數據保存到preference,調用用戶首選項實例的put接口
try {
await preference.put('screenBrightness', JSON.stringify(screenBrightness));
} catch (err) {
Logger.error('[PreferenceModel]', `Failed to put value, Cause: ${err}`);
}
// 使用flush方法將preferences實例的數據存儲到持久化文件,調用用戶首選項實例的flush接口
await preference.flush();
}
// 獲取數據,調用用戶首選項實例的get接口
async getPreference() {
let screenBrightness = '';
if (preference === null) {
await this.getPreferencesFromStorage();
}
try {
screenBrightness = <string> await preference.get('screenBrightness', '');
} catch (err) {
Logger.error('[PreferenceModel]', `Failed to get value, Cause: ${err}`);
}
// 如果判斷數據為空則提示用戶先輸入數據
if (screenBrightness === '') {
this.showToastMessage($r('app.string.data_is_null_msg'));
return;
}
this.showToastMessage($r('app.string.read_success_msg'));
return JSON.parse(screenBrightness);
}
// 校驗用戶輸入是否為空
checkData(screenBrightness:ScreenBrightness) {
if (screenBrightness.brightSwitch === '' || screenBrightness.defaultValue === '') {
this.showToastMessage($r('app.string.fruit_input_null_msg'));
return true;
}
return false;
}
// 點擊保存按鈕保存數據
writeData(screenBrightness:ScreenBrightness) {
// Check whether the data is null.
let isDataNull = this.checkData(screenBrightness);
if (isDataNull) {
return;
}
// The data is inserted into the preferences database if it is not empty.
this.putPreference(screenBrightness);
this.showToastMessage($r('app.string.write_success_msg'));
}
// 消息彈框
showToastMessage(message: Resource) {
promptAction.showToast({
message: message,
duration: 3000
});
};
}
UI中主要包含兩大部分:文本和輸入框,按鈕。將這兩部分分別抽取為子組件,在主頁中進行調用。具體代碼如下:
文本和輸入框子組件:
import ScreenBrightness from '../common/bean/Brightness';
@Component
export default struct TextItemComponent {
private textResource: Resource;
private placeholderResource: Resource;
private marginBottom: string;
private marginTop: string;
private textInputType: InputType;
private textFlag: number;
@Link screenBrightness: ScreenBrightness;
private textInputCallBack: (value: string) => void;
aboutToAppear() {
if (this.textFlag === 0) {
this.marginTop = '8%';
this.marginBottom = '4%';
this.textInputType = InputType.Normal;
} else {
this.marginBottom = '321vp';
this.textInputType = InputType.Number;
}
}
build() {
Column() {
// 文本
Text(this.textResource)
.fontSize(25)
.height('3.2%')
.width('100%')
.fontColor("#182431")
.letterSpacing('1.58')
.fontWeight(500)
.margin({
bottom: '2%',
left: '7%',
top: this.marginTop
})
// 輸入框
TextInput({
placeholder: this.placeholderResource,
text: this.textFlag === 0 ? (this.screenBrightness.brightSwitch) : (this.screenBrightness.defaultValue)
})
.placeholderFont({ size: 20, weight: 500 })
.placeholderColor("#BDC1C4")
.caretColor(Color.Blue)
.type(this.textInputType)
.height('7%')
.width('93%')
.margin({ bottom: this.marginBottom })
.fontSize(20)
.fontColor("#182431")
.fontWeight(500)
.backgroundColor("#FFFFFF")
.onChange((value: string) => {
this.textInputCallBack(value);
})
}
}
}
按鈕子組件:
import PreferenceModel from '../model/PreferenceModel';
import ButtonItemData from '../common/bean/ButtonItemData';
import ScreenBrightness from '../common/bean/Brightness';
@Component
export default struct ButtonComponent {
private buttonItemValues: Array<ButtonItemData> = this.getButtonItemValues();
@Link screenBrightness: ScreenBrightness;
build() {
Column() {
ForEach(this.buttonItemValues, (item) => {
Button(item.text, { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor("#E8A027")
.width('87%')
.height('6%')
.fontWeight(500)
.fontSize(20)
.margin({ bottom: '24vp' })
.onClick(() => {
item.clickMethod();
})
}, item => JSON.stringify(item))
}
}
// 在foreach中渲染Button組件時傳入不同按鈕的參數
getButtonItemValues() {
let values: Array<ButtonItemData> = [
new ButtonItemData(
'保存數據',
() => {
// 調用保存方法
PreferenceModel.writeData(this.screenBrightness);
}
),
new ButtonItemData(
'讀取數據',
() => {
// 調用讀取方法
PreferenceModel.getPreference().then(resultData => {
this.screenBrightness = resultData;
console.info('dbdata is '+JSON.stringify(resultData))
});
}
),
new ButtonItemData(
'刪除數據',
() => {
// 調用刪除方法
PreferenceModel.deletePreferences();
// 數據刪除后將相關內容置為空
this.screenBrightness.brightSwitch = '';
this.screenBrightness.defaultValue = ''
}
)
];
return values;
}
}
構建首頁UI。
在頁面生命周期的aboutToAppear中調用自定義首選項類的getPreference方法獲取到保存的數據,這樣如果用戶之前有保存數據的話,進入應用中就可以顯示之前保存的數據。
具體代碼如下:
import PreferenceModel from '../model/PreferenceModel';
import ButtonComponent from '../view/ButtonComponent';
import TextItemComponent from '../view/TextItemComponent';
import ScreenBrightness from '../common/bean/Brightness';
@Entry
@Component
struct Setting {
@State screenBrightness: ScreenBrightness = new ScreenBrightness('', '');
build() {
Column() {
// 亮度調節文本及文本框
TextItemComponent({
textResource: $r('app.string.brightness_text'),
placeholderResource: $r('app.string.brightness_placeholder'),
textFlag: 0,
screenBrightness: $screenBrightness,
textInputCallBack: (value) => {
this.screenBrightness.brightSwitch = value;
}
})
// 設定值文本及文本框
TextItemComponent({
textResource: $r('app.string.defaultValue_text'),
placeholderResource: $r('app.string.defaultValue_placeholder'),
textFlag: 1,
screenBrightness: $screenBrightness,
textInputCallBack: (value) => {
this.screenBrightness.defaultValue = value;
}
})
// 按鈕
ButtonComponent({ screenBrightness: $screenBrightness })
}
.width('100%')
.height('100%')
.backgroundColor("#F1F3F5")
}
async aboutToAppear() {
await PreferenceModel.getPreferencesFromStorage();
// 獲取到之前保存的數據,顯示在輸入框中
PreferenceModel.getPreference().then(resultData => {
this.screenBrightness = resultData;
});
}
}
完整代碼
由于開發步驟中已經展示了大部分完整代碼,此處補充前文中未呈現的兩個數據類:
亮度數據類:
export default class ScreenBrightness {
// 亮度調節
brightSwitch: string;
// 設定值
defaultValue: string;
constructor(brightSwitch: string, defaultValue: string) {
this.brightSwitch = brightSwitch;
this.defaultValue = defaultValue;
}
}
按鈕數據類:
export default class ButtonItemData {
// 按鈕文本
text: string;
// 按鈕點擊事件觸發的方法
clickMethod: () => void;
constructor(text: string, clickMethod: () => void) {
this.text = text;
this.clickMethod = clickMethod;
}
}