应用异常处理
介绍
本示例介绍了通过应用事件打点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 componentFunctionDescription({title: $r('app.string.application_exception_application_fault_title'),content: $r('app.string.application_exception_application_fault_description')})// Abnormal information display componentFaultArea()// Constructing Abnormal ComponentsFaultConstruction()}.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 instanceawait 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 storagethis.getFaultMessage();// Reset appEventGroups in AppStorage to avoid adding duplicate dataAppStorage.setOrCreate('appEventGroups', []);}// Obtain application exception informationasync getFaultMessage() {Logger.info(TAG, `getAppEventGroups start`);if (this.appEventGroups && this.appEventGroups.length > 0) {// Traverse event groupsthis.appEventGroups.forEach((eventGroup: hiAppEvent.AppEventGroup) => {// Traverse the collection of event objectseventGroup.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 faultMessagethis.faultDataSource.pushData(message);})})}// Knowledge point: Persisting storage exception information collectionthis.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 informationif (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 eventText(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 eventconst 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 500mswhile (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 signthis.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 0this.faultDataSourceLength = 0;// Update the index of clicked abnormal eventsthis.eventIndex = index;// Execute system crash operation after 3ssetTimeout(() => {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 eventshiAppEvent.addWatcher({// Developers can customize observer names, which the system will use to identify different observersname: 'mst',// Developers can subscribe to system events of interest, where they have subscribed to crash eventsappEventFilters: [{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 startsonReceive: 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 componentFunctionDescription({title: $r('app.string.application_exception_application_fault_title'),content: $r('app.string.application_exception_application_fault_description')})// Abnormal information display componentFaultArea()// Constructing Abnormal ComponentsFaultConstruction()}.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 instanceawait 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 storagethis.getFaultMessage();// Reset appEventGroups in AppStorage to avoid adding duplicate dataAppStorage.setOrCreate('appEventGroups', []);}// Obtain application exception informationasync getFaultMessage() {Logger.info(TAG, `getAppEventGroups start`);if (this.appEventGroups && this.appEventGroups.length > 0) {// Traverse event groupsthis.appEventGroups.forEach((eventGroup: hiAppEvent.AppEventGroup) => {// Traverse the collection of event objectseventGroup.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 faultMessagethis.faultDataSource.pushData(message);})})}// Knowledge point: Persisting storage exception information collectionthis.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 informationif (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 eventText(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 eventconst 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 500mswhile (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 signthis.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 0this.faultDataSourceLength = 0;// Update the index of clicked abnormal eventsthis.eventIndex = index;// Execute system crash operation after 3ssetTimeout(() => {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 listenerprivate listeners: DataChangeListener[] = [];// Data sources that require data iterationprivate originDataArray: string[] = [];// Obtain the length of datapublic totalCount(): number {return 0;}// Get specified data itemspublic 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 listeningregisterDataChangeListener(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 componentunregisterDataChangeListener(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 componentsnotifyDataReload(): void {this.listeners.forEach(listener => {listener.onDataReloaded();})}// Notify LazyForEach component to add sub components at// the index corresponding to the indexnotifyDataAdd(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 rebuiltnotifyDataChange(index: number): void {this.listeners.forEach(listener => {listener.onDataChange(index);})}// Notify LazyForEach component to delete the subcomponent at the index corresponding to the indexnotifyDataDelete(index: number): void {this.listeners.forEach(listener => {listener.onDataDelete(index);})}
}export class FaultDataSource extends BasicDataSource {// Lazy loading dataprivate faultMessage: Array<string> = [];// Knowledge point: Obtaining the data length of lazy loading data sourcestotalCount(): number {return this.faultMessage.length;}// Get specified data itemsgetData(index: number): string {return this.faultMessage[index];}// Knowledge point: Storing data into lazy loading data sourcespushData(data: string): void {this.faultMessage.unshift(data);// Add data to the array headerthis.notifyDataAdd(0);AppStorage.setOrCreate('faultDataSourceLength', this.totalCount());}// Knowledge point: Persisting storage exception information collectionpersistenceStorage(): 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 instancepublic 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 informationawait 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 methoddataPreferencesManager.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 methodconst 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 sourcefaultData.forEach((item: string) => {faultDataSource.pushData(item);})// Bidirectional data binding lazy loading data source length, updating data source lengthAppStorage.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 methoddataPreferencesManager.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 methodconst 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内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!
鸿蒙【北向应用开发+南向系统层开发】文档
鸿蒙【基础+实战项目】视频
鸿蒙面经
为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!