应用异常处理
介绍
本示例介绍了通过应用事件打点hiAppEvent获取上一次应用异常信息的方法,主要分为应用崩溃、应用卡死两种。
效果图预览
使用说明
- 点击构建应用崩溃事件,3s之后应用退出,然后打开应用进入应用异常页面,隔1min左右后,显示上次异常退出信息。
- 点击构建应用卡死事件,需手动退出,然后打开应用进入应用异常页面,隔1min左右后,显示上次异常退出信息。
实现思路
- 构建应用异常。源码参考[Index.ets]
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { hiAppEvent } from '@kit.PerformanceAnalysisKit';
import { PreferencesManager } from '../model/PreferencesManager';
import { BUTTON_TEXT } from '../model/MockData';
import { FaultDataSource } from '../model/DataSource';
import { Logger } from '../log/Logger';
const TAG: string = 'FaultLogger'; // Abnormal Application Page Tag
const DELAY_TIME: number = 3000;
@Entry
@Component
struct ApplicationExceptionView {
// Initialize the index of the clicked exception event
@Provide eventIndex: number = -1;
build() {
Column() {
// Scenario description component
FunctionDescription({
title: $r('app.string.application_exception_application_fault_title'),
content: $r('app.string.application_exception_application_fault_description')
})
// Abnormal information display component
FaultArea()
// Constructing Abnormal Components
FaultConstruction()
}
.padding($r('app.string.ohos_id_card_padding_start'))
.backgroundColor($r('app.color.ohos_id_color_sub_background'))
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.height($r('app.string.ohos_global_state_dialog_hundred_percent'))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])
}
}
@Component
struct FaultArea {
// Perform bidirectional data binding on the array length of lazy loading data sources
@StorageLink('faultDataSourceLength') faultDataSourceLength: number = 0;
// Bidirectional data binding event group, bound to AppStorage. setOrCreate,
// this variable changes and triggers the getFaultMessage function
@StorageLink('appEventGroups') @Watch('getFaultMessage') appEventGroups: Array<hiAppEvent.AppEventGroup> = [];
// Abnormal trigger sign
@StorageLink('faultSign') faultSign: boolean = false;
// The index of the clicked abnormal event
@Consume eventIndex: number;
// Data source for lazy loading
@State faultDataSource: FaultDataSource = new FaultDataSource();
private scroller: Scroller = new Scroller();
async aboutToAppear() {
Logger.info(TAG, `aboutToAppear start`);
// Get Preferences instance
await PreferencesManager.getPreferences(this.faultDataSource);
// First, retrieve data from the persistent storage,
// then add the previous application exception information to the list header,
// and update the persistent storage
this.getFaultMessage();
// Reset appEventGroups in AppStorage to avoid adding duplicate data
AppStorage.setOrCreate('appEventGroups', []);
}
// Obtain application exception information
async getFaultMessage() {
Logger.info(TAG, `getAppEventGroups start`);
if (this.appEventGroups && this.appEventGroups.length > 0) {
// Traverse event groups
this.appEventGroups.forEach((eventGroup: hiAppEvent.AppEventGroup) => {
// Traverse the collection of event objects
eventGroup.appEventInfos.forEach(async (eventInfo: hiAppEvent.AppEventInfo) => {
let message: string = '';
message += `HiAppEvent eventInfo.domain=${eventInfo.domain}\n`
+ `HiAppEvent eventInfo.name=${eventInfo.name}\n`
+ `HiAppEvent eventInfo.eventType=${eventInfo.eventType}\n`
+ `HiAppEvent eventInfo.params.time=${eventInfo.params['time']}\n`
+ `HiAppEvent eventInfo.params.crash_type=${eventInfo.params['crash_type']}\n`
+ `HiAppEvent eventInfo.params.foreground=${eventInfo.params['foreground']}\n`
+ `HiAppEvent eventInfo.params.bundle_version=${eventInfo.params['bundle_version']}\n`
+ `HiAppEvent eventInfo.params.bundle_name=${eventInfo.params['bundle_name']}\n`
+ `HiAppEvent eventInfo.params.exception=${JSON.stringify(eventInfo.params['exception'])}\n`
+ `HiAppEvent eventInfo.params.hilog.size=${eventInfo.params['hilog'].length}\n`;
// Knowledge point: Storing exception information in the array faultMessage
this.faultDataSource.pushData(message);
})
})
}
// Knowledge point: Persisting storage exception information collection
this.faultDataSource.persistenceStorage();
}
build() {
List({ scroller:this.scroller }) {
// Add a judgment, if the number of information in the set of abnormal information is greater than 0, traverse the abnormal information
if (this.faultDataSourceLength > 0) {
LazyForEach(this.faultDataSource, (message: string) => {
ListItem() {
Text(message)
.textAlign(TextAlign.Start)
}
}, (item: string) => item)
} else {
ListItem() {
// Respond to specified information based on the index of the clicked event
Text(this.eventIndex === 0 ? $r('app.string.application_exception_crash_event_message') :
(this.eventIndex === 1 ? $r('app.string.application_exception_freeze_event_message') :
(this.faultSign ? $r('app.string.application_exception_data_delay_toast') :
$r('app.string.application_exception_no_message'))))
}
}
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.height($r('app.string.ohos_id_elements_list_high'))
.borderRadius($r('app.string.ohos_id_corner_radius_default_m'))
.padding($r('app.string.ohos_id_card_padding_start'))
.margin({ top: $r('app.string.ohos_id_elements_margin_vertical_l') })
.backgroundColor(Color.White)
}
}
@Component
struct FaultConstruction {
// The index of the clicked abnormal event
@Consume eventIndex: number;
// Perform bidirectional data binding on the array length of lazy loading data sources
@StorageLink('faultDataSourceLength') faultDataSourceLength: number = 0;
// Abnormal trigger sign
@StorageLink('faultSign') faultSign: boolean = false;
handleOperate(index: number) {
switch (index) {
case 0:
// Note: This is a deliberately constructed bug
// Construct an APP-CRASH scenario in the button click function to trigger an application crash event
const result: object = JSON.parse('');
break;
case 1:
// Note: This is a deliberately constructed bug
// Construct an APP-FREEZE scenario in the button click function,
// trigger the application freeze event, and execute an infinite loop after 500ms
while (true) {
}
default:
break;
}
}
build() {
Stack() {
Column(){
ForEach(BUTTON_TEXT, (item: string, index: number) => {
Button(item)
.type(ButtonType.Capsule)
.size({ width: $r('app.string.ohos_global_state_dialog_hundred_percent') })
.borderRadius($r('app.string.ohos_id_corner_radius_default_m'))
.margin({ top: $r('app.string.ohos_id_button_margin_top') })
.onClick(() => {
// Abnormal trigger sign
this.faultSign = true;
PreferencesManager.putFaultSign();
// When clicking on an exception, clear the page information data
// and display the exception description information.
// To control the display of page information data,
// this variable needs to be set to 0
this.faultDataSourceLength = 0;
// Update the index of clicked abnormal events
this.eventIndex = index;
// Execute system crash operation after 3s
setTimeout(() => {
this.handleOperate(index);
}, DELAY_TIME);
})
}, (item: string) => JSON.stringify(item))
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.margin({ bottom: $r('app.string.ohos_id_button_margin_bottom')})
.align(Alignment.Bottom)
.flexGrow(1)
}
}
@Component
struct FunctionDescription {
private title: ResourceStr = '';
private content: ResourceStr = '';
build() {
Column() {
Row() {
Text(this.title)
.fontSize($r('app.string.ohos_id_text_size_headline'))
.fontWeight(FontWeight.Medium)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.margin({ bottom: $r('app.string.ohos_id_elements_margin_vertical_m') })
Row() {
Text(this.content)
.wordBreak(WordBreak.NORMAL)
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.padding($r('app.string.ohos_id_card_padding_start'))
}
}
- 应用退出后,进入本页面,等待订阅消息通知,待收到订阅消息后,通过EventSubscription.ets中的onReceive函数,接收到异常信息数据,并通过AppStorage.setOrCreate(‘appEventGroups’,异常信息数据)双向绑定异常信息,源码参考代码可参考[EventSubscription.ets]
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { hiAppEvent } from '@kit.PerformanceAnalysisKit';
import { Logger } from '../log/Logger';
const TAG: string = 'eventSubscription';
export function eventSubscription(): void {
// Add application event observer method, which can be used to subscribe to application events
hiAppEvent.addWatcher({
// Developers can customize observer names, which the system will use to identify different observers
name: 'mst',
// Developers can subscribe to system events of interest, where they have subscribed to crash events
appEventFilters: [
{
domain: hiAppEvent.domain.OS,
names: [hiAppEvent.event.APP_CRASH, hiAppEvent.event.APP_FREEZE]
}
],
// Knowledge point: Obtain event group information.
// Developers can implement subscription callback functions themselves,
// and crash and freeze events will be called back to developers the next time the application starts
onReceive: async (domain: string, appEventGroups: Array<hiAppEvent.AppEventGroup>) => {
Logger.info(TAG, `HiAppEvent onReceive: domain=${domain}`);
// Obtain event group information and perform bidirectional data binding with
// @StorageLink('faultMessage') faultMessage in the ApplicationException file
// Performance concerns: If developers have synchronized code that requires time-consuming operations,
// it is recommended to start worker or taskpool threads to handle it.
// But if developers use storage and preferences, they can simply call them.
AppStorage.setOrCreate('appEventGroups', appEventGroups);
}
});
}
- @StorageLink(‘appEventGroups’)接收订阅事件函数传递的事件组信息,调用getFaultMessage函数对信息进行处理,将处理后的信息通过 this.faultDataSource.pushData(message) 添加到懒加载数据源中,并通过this.faultDataSource.persistenceStorage()执行持久化存储,最后通过使用LazyForEach将数据信息加载到页面上。具体源码参考[Index.ets]
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { hiAppEvent } from '@kit.PerformanceAnalysisKit';
import { PreferencesManager } from '../model/PreferencesManager';
import { BUTTON_TEXT } from '../model/MockData';
import { FaultDataSource } from '../model/DataSource';
import { Logger } from '../log/Logger';
const TAG: string = 'FaultLogger'; // Abnormal Application Page Tag
const DELAY_TIME: number = 3000;
@Entry
@Component
struct ApplicationExceptionView {
// Initialize the index of the clicked exception event
@Provide eventIndex: number = -1;
build() {
Column() {
// Scenario description component
FunctionDescription({
title: $r('app.string.application_exception_application_fault_title'),
content: $r('app.string.application_exception_application_fault_description')
})
// Abnormal information display component
FaultArea()
// Constructing Abnormal Components
FaultConstruction()
}
.padding($r('app.string.ohos_id_card_padding_start'))
.backgroundColor($r('app.color.ohos_id_color_sub_background'))
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.height($r('app.string.ohos_global_state_dialog_hundred_percent'))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])
}
}
@Component
struct FaultArea {
// Perform bidirectional data binding on the array length of lazy loading data sources
@StorageLink('faultDataSourceLength') faultDataSourceLength: number = 0;
// Bidirectional data binding event group, bound to AppStorage. setOrCreate,
// this variable changes and triggers the getFaultMessage function
@StorageLink('appEventGroups') @Watch('getFaultMessage') appEventGroups: Array<hiAppEvent.AppEventGroup> = [];
// Abnormal trigger sign
@StorageLink('faultSign') faultSign: boolean = false;
// The index of the clicked abnormal event
@Consume eventIndex: number;
// Data source for lazy loading
@State faultDataSource: FaultDataSource = new FaultDataSource();
private scroller: Scroller = new Scroller();
async aboutToAppear() {
Logger.info(TAG, `aboutToAppear start`);
// Get Preferences instance
await PreferencesManager.getPreferences(this.faultDataSource);
// First, retrieve data from the persistent storage,
// then add the previous application exception information to the list header,
// and update the persistent storage
this.getFaultMessage();
// Reset appEventGroups in AppStorage to avoid adding duplicate data
AppStorage.setOrCreate('appEventGroups', []);
}
// Obtain application exception information
async getFaultMessage() {
Logger.info(TAG, `getAppEventGroups start`);
if (this.appEventGroups && this.appEventGroups.length > 0) {
// Traverse event groups
this.appEventGroups.forEach((eventGroup: hiAppEvent.AppEventGroup) => {
// Traverse the collection of event objects
eventGroup.appEventInfos.forEach(async (eventInfo: hiAppEvent.AppEventInfo) => {
let message: string = '';
message += `HiAppEvent eventInfo.domain=${eventInfo.domain}\n`
+ `HiAppEvent eventInfo.name=${eventInfo.name}\n`
+ `HiAppEvent eventInfo.eventType=${eventInfo.eventType}\n`
+ `HiAppEvent eventInfo.params.time=${eventInfo.params['time']}\n`
+ `HiAppEvent eventInfo.params.crash_type=${eventInfo.params['crash_type']}\n`
+ `HiAppEvent eventInfo.params.foreground=${eventInfo.params['foreground']}\n`
+ `HiAppEvent eventInfo.params.bundle_version=${eventInfo.params['bundle_version']}\n`
+ `HiAppEvent eventInfo.params.bundle_name=${eventInfo.params['bundle_name']}\n`
+ `HiAppEvent eventInfo.params.exception=${JSON.stringify(eventInfo.params['exception'])}\n`
+ `HiAppEvent eventInfo.params.hilog.size=${eventInfo.params['hilog'].length}\n`;
// Knowledge point: Storing exception information in the array faultMessage
this.faultDataSource.pushData(message);
})
})
}
// Knowledge point: Persisting storage exception information collection
this.faultDataSource.persistenceStorage();
}
build() {
List({ scroller:this.scroller }) {
// Add a judgment, if the number of information in the set of abnormal information is greater than 0, traverse the abnormal information
if (this.faultDataSourceLength > 0) {
LazyForEach(this.faultDataSource, (message: string) => {
ListItem() {
Text(message)
.textAlign(TextAlign.Start)
}
}, (item: string) => item)
} else {
ListItem() {
// Respond to specified information based on the index of the clicked event
Text(this.eventIndex === 0 ? $r('app.string.application_exception_crash_event_message') :
(this.eventIndex === 1 ? $r('app.string.application_exception_freeze_event_message') :
(this.faultSign ? $r('app.string.application_exception_data_delay_toast') :
$r('app.string.application_exception_no_message'))))
}
}
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.height($r('app.string.ohos_id_elements_list_high'))
.borderRadius($r('app.string.ohos_id_corner_radius_default_m'))
.padding($r('app.string.ohos_id_card_padding_start'))
.margin({ top: $r('app.string.ohos_id_elements_margin_vertical_l') })
.backgroundColor(Color.White)
}
}
@Component
struct FaultConstruction {
// The index of the clicked abnormal event
@Consume eventIndex: number;
// Perform bidirectional data binding on the array length of lazy loading data sources
@StorageLink('faultDataSourceLength') faultDataSourceLength: number = 0;
// Abnormal trigger sign
@StorageLink('faultSign') faultSign: boolean = false;
handleOperate(index: number) {
switch (index) {
case 0:
// Note: This is a deliberately constructed bug
// Construct an APP-CRASH scenario in the button click function to trigger an application crash event
const result: object = JSON.parse('');
break;
case 1:
// Note: This is a deliberately constructed bug
// Construct an APP-FREEZE scenario in the button click function,
// trigger the application freeze event, and execute an infinite loop after 500ms
while (true) {
}
default:
break;
}
}
build() {
Stack() {
Column(){
ForEach(BUTTON_TEXT, (item: string, index: number) => {
Button(item)
.type(ButtonType.Capsule)
.size({ width: $r('app.string.ohos_global_state_dialog_hundred_percent') })
.borderRadius($r('app.string.ohos_id_corner_radius_default_m'))
.margin({ top: $r('app.string.ohos_id_button_margin_top') })
.onClick(() => {
// Abnormal trigger sign
this.faultSign = true;
PreferencesManager.putFaultSign();
// When clicking on an exception, clear the page information data
// and display the exception description information.
// To control the display of page information data,
// this variable needs to be set to 0
this.faultDataSourceLength = 0;
// Update the index of clicked abnormal events
this.eventIndex = index;
// Execute system crash operation after 3s
setTimeout(() => {
this.handleOperate(index);
}, DELAY_TIME);
})
}, (item: string) => JSON.stringify(item))
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.margin({ bottom: $r('app.string.ohos_id_button_margin_bottom')})
.align(Alignment.Bottom)
.flexGrow(1)
}
}
@Component
struct FunctionDescription {
private title: ResourceStr = '';
private content: ResourceStr = '';
build() {
Column() {
Row() {
Text(this.title)
.fontSize($r('app.string.ohos_id_text_size_headline'))
.fontWeight(FontWeight.Medium)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.margin({ bottom: $r('app.string.ohos_id_elements_margin_vertical_m') })
Row() {
Text(this.content)
.wordBreak(WordBreak.NORMAL)
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
}
.width($r('app.string.ohos_global_state_dialog_hundred_percent'))
.padding($r('app.string.ohos_id_card_padding_start'))
}
}
- 以上代码中有引用懒加载数据类和持久化存储类,源码可参考[DataSource.ets]
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PreferencesManager } from './PreferencesManager';
// Basic implementation of IDataSource to handle data listener
class BasicDataSource implements IDataSource {
// Data change listener
private listeners: DataChangeListener[] = [];
// Data sources that require data iteration
private originDataArray: string[] = [];
// Obtain the length of data
public totalCount(): number {
return 0;
}
// Get specified data items
public getData(index: number): string {
return this.originDataArray[index];
}
// This method is called on the framework side to add a listener listener
// to the LazyForEach component's data source for listening
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
// This method is called on the framework side to remove listener listening
// at the data source for the corresponding LazyForEach component
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
// Notify LazyForEach component to overload all child components
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
// Notify LazyForEach component to add sub components at
// the index corresponding to the index
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
// Notify the LazyForEach component that there is a change in data at
// the index corresponding to the index, and that the subcomponent needs to be rebuilt
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
// Notify LazyForEach component to delete the subcomponent at the index corresponding to the index
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
}
export class FaultDataSource extends BasicDataSource {
// Lazy loading data
private faultMessage: Array<string> = [];
// Knowledge point: Obtaining the data length of lazy loading data sources
totalCount(): number {
return this.faultMessage.length;
}
// Get specified data items
getData(index: number): string {
return this.faultMessage[index];
}
// Knowledge point: Storing data into lazy loading data sources
pushData(data: string): void {
this.faultMessage.unshift(data);
// Add data to the array header
this.notifyDataAdd(0);
AppStorage.setOrCreate('faultDataSourceLength', this.totalCount());
}
// Knowledge point: Persisting storage exception information collection
persistenceStorage(): void {
PreferencesManager.putFaultMessage(this.faultMessage);
}
}
和参考源码:[PreferencesManager.ets]
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { preferences as dataPreferences } from '@kit.ArkData';
import { BusinessError } from '@kit.BasicServicesKit';
import { FaultDataSource } from '../model/DataSource';
import { Logger } from '../log/Logger';
// Knowledge point: Initialize Preferences instances for persistent storage of
// exception information and the ability to retrieve persistent data
let dataPreferencesManager: dataPreferences.Preferences = {} as dataPreferences.Preferences;
export class PreferencesManager {
// Get Preferences instance
public static async getPreferences(faultDataSource: FaultDataSource): Promise<void> {
Logger.info('getPreferences start.');
try {
let val: dataPreferences.Preferences = await (dataPreferences.getPreferences(AppStorage.get('context'),
'myStore') as Promise<dataPreferences.Preferences>);
dataPreferencesManager = val;
Logger.info('Succeeded in getting preferences.');
// Get abnormal information
await PreferencesManager.getFaultMessage(faultDataSource);
await PreferencesManager.getFaultSign();
} catch (err) {
Logger.error('Failed to get preferences');
}
}
/**
* Storing abnormal data information
* @Param faultMessage exception information set
*/
public static async putFaultMessage(faultMessage: Array<string>): Promise<void> {
Logger.info(`putMessage start`);
try {
// Knowledge point: Storing data through the dataPreferencesManager.put method
dataPreferencesManager.put('faultMessage', JSON.stringify(faultMessage), async (err: BusinessError) => {
if (err) {
Logger.error(`Failed to put value of 'faultMessage'. code =` + err.code + ', message =' + err.message);
return;
}
Logger.info('Succeeded in putting value of faultMessage.');
dataPreferencesManager.flush();
})
} catch (err) {
Logger.error(`Failed to put value of 'catch err'. code =` + err.code + ', message =' + err.message);
}
}
/**
* Get abnormal data information
* @Param faultMessage exception information set
*/
public static async getFaultMessage(faultDataSource: FaultDataSource): Promise<void> {
Logger.info(`getFaultMessage start`);
try {
// Knowledge point: Obtaining abnormal information data through the dataPreferencesManager.get method
const data: dataPreferences.ValueType = await dataPreferencesManager.get('faultMessage', []);
if (typeof data === 'string') {
const faultData: Array<string> = JSON.parse(data);
// Add abnormal data to lazy loading data source
faultData.forEach((item: string) => {
faultDataSource.pushData(item);
})
// Bidirectional data binding lazy loading data source length, updating data source length
AppStorage.setOrCreate('faultDataSourceLength', faultDataSource.totalCount());
Logger.info('Succeeded in getting value of faultMessage.');
}
} catch (err) {
Logger.error(`Failed to get value of 'catch err'. code =` + err.code + ', message =' + err.message);
}
}
/**
* Storage data sign
*/
public static async putFaultSign(): Promise<void> {
Logger.info(`putMessage start`);
try {
// Knowledge point: Storing data through the dataPreferencesManager.put method
dataPreferencesManager.put('faultSign', JSON.stringify(true), async (err: BusinessError) => {
if (err) {
Logger.error(`Failed to put value of 'faultSign'. code =` + err.code + ', message =' + err.message);
return;
}
Logger.info('Succeeded in putting value of faultSign.');
dataPreferencesManager.flush();
})
} catch (err) {
Logger.error(`putFaultSign Failed to put value of 'catch err'. code =` + err.code + ', message =' + err.message);
}
}
/**
* Get abnormal data information
*/
public static async getFaultSign(): Promise<void> {
Logger.info(`getFaultMessage start`);
let faultSign: boolean = false;
try {
// Knowledge point: Obtain exception identifiers through the dataPreferencesManager.get method
const data: dataPreferences.ValueType = await dataPreferencesManager.get('faultSign', faultSign);
if (typeof data === 'string') {
faultSign = JSON.parse(data);
AppStorage.setOrCreate('faultSign', faultSign);
}
} catch (err) {
Logger.error(`getFaultSign Failed to get value of 'catch err'. code =` + err.code + ', message =' + err.message);
}
}
}
以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下:
内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!
鸿蒙【北向应用开发+南向系统层开发】文档
鸿蒙【基础+实战项目】视频
鸿蒙面经
为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!