当前位置: 首页 > news >正文

Openharmony应用开发之Ability异常退出与UIAbility数据备份开发实战

概述

AbilityStage在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。

AbilityStage拥有onCreate()、onDestroy()生命周期回调和onAcceptWant()、onConfigurationUpdate()、onMemoryLevel()、onNewProcessRequest()、onPrepareTermination()等事件回调。

  • onCreate()生命周期回调:在开始加载对应Module的第一个应用组件(如UIAbility组件或具体扩展能力的ExtensionAbility组件实例之前会先创建AbilityStage,并在AbilityStage创建完成之后执行其onCreate()生命周期回调。AbilityStage模块提供在Module加载的时候,通知开发者,可以在此进行该Module的初始化(如资源预加载、线程创建等)。

  • onAcceptWant()事件回调:UIAbility指定实例模式specified启动模式)启动时候触发的事件回调。

  • onConfigurationUpdate()事件回调:当系统全局配置(例如系统语言、深浅色等)发生变更时触发的事件回调,配置项均定义在Configuration类中。

  • onMemoryLevel()事件回调:当系统调整内存时触发的事件回调。应用被切换到后台时,系统会将在后台的应用保留在缓存中。即使应用处于缓存中,也会影响系统整体性能。当系统资源不足时,系统会通过多种方式从应用中回收内存,必要时会完全停止应用,从而释放内存用于执行关键任务。为了进一步保持系统内存的平衡,避免系统停止用户的应用进程,可以在AbilityStage中的onMemoryLevel()生命周期回调中订阅系统内存的变化情况,释放不必要的资源。

  • onNewProcessRequest()事件回调:UIAbility启动时触发的事件回调。通过该回调,开发者可以指定每个UIAbility启动时是否在独立的进程中创建。该回调返回一个开发者自定义字符串标识,如果返回的字符串标识为开发者曾创建的,则复用该标识所对应的进程,否则创建新的进程。需要注意该回调需要配合在module.json5中声明isolationProcess字段为true。当前仅在2in1设备上生效。

  • onPrepareTermination()事件回调:当应用被用户关闭时调用,可用于询问用户选择立即执行操作还是取消操作。开发者通过在回调中返回AbilityConstant.PrepareTermination中定义的枚举类型通知系统是否继续执行关闭动作。当前仅在2in1设备上生效。

  • onDestroy()生命周期回调:当对应Module的最后一个Ability实例退出后触发。此方法仅在应用正常销毁时触发。当应用程序异常退出或被终止时,将不会调用此方法。

例如onCreate回调

import { AbilityStage, Want } from '@kit.AbilityKit';export default class MyAbilityStage extends AbilityStage {onCreate(): void {// 应用HAP首次加载时触发,可以在此执行该Module的初始化操作(例如资源预加载、线程创建等)。}onAcceptWant(want: Want): string {// 仅specified模式下触发return 'MyAbilityStage';}
}

1. Ability的设计使用场景

  • 应用的多Module开发:应用可通过不同类型的Module(HAP、HAR、HSP)来实现应用的功能开发。其中,HAP用于实现应用的功能和特性,HAR与HSP用于实现代码和资源的共享。
  • 应用内的交互:应用内的不同组件之间可以相互跳转。比如,在支付应用中,通过入口UIAbility组件启动收付款UIAbility组件。
  • 应用间的交互:当前应用可以启动其他应用,来完成某个任务或操作。比如,启动浏览器应用来打开网站、启动文件应用来浏览或编辑文件等。
  • 应用的跨设备流转:通过应用的跨端迁移和多端协同,获得更好的使用体验。比如,在平板上播放的视频,迁移到智慧屏继续播放。
  • 在应用使用场景中,当用户在应用内点击某个按钮时,经常需要拉起指定UIAbility组件来完成某些特定任务。在启动UIAbility时,指定了abilityName和bundleName参数,可以使用显式Want方式启动UIAbility。

2.监听系统环境变量的变化

下面以监听系统环境变量的变化的开发场景为例,介绍AbilityStage组件回调函数的使用。

  • 在onCreate()生命周期中,通过EnvironmentCallback来监听系统环境变化,例如系统语言、深浅色模式、屏幕方向、字体大小缩放比例、字体粗细缩放比例等信息。

  • 当系统全局配置发生变更时,会触发EnvironmentCallback中的onConfigurationUpdated()回调,并打印相关信息。

  • 通过关闭应用进程,可以触发AbilityStage的onDestroy()生命周期回调。

    import { EnvironmentCallback, AbilityStage } from '@kit.AbilityKit';
    import { BusinessError } from '@kit.BasicServicesKit';export default class MyAbilityStage extends AbilityStage {onCreate(): void {console.log('AbilityStage onCreate');let envCallback: EnvironmentCallback = {onConfigurationUpdated(config) {console.info(`envCallback onConfigurationUpdated success: ${JSON.stringify(config)}`);let language = config.language; //应用程序的当前语言let colorMode = config.colorMode; //深浅色模式let direction = config.direction; //屏幕方向let fontSizeScale = config.fontSizeScale; //字体大小缩放比例let fontWeightScale = config.fontWeightScale; //字体粗细缩放比例},onMemoryLevel(level) {console.log(`onMemoryLevel level: ${level}`);}};try {let applicationContext = this.context.getApplicationContext();let callbackId = applicationContext.on('environment', envCallback);console.log(`callbackId: ${callbackId}`);} catch (paramError) {console.error(`error: ${(paramError as BusinessError).code}, ${(paramError as BusinessError).message}`);}}onDestroy(): void {// 通过onDestroy()方法,可以监听到Ability的销毁事件。console.log('AbilityStage onDestroy');}
    }
    

3.UIAbility备份恢复

场景介绍

当应用后台运行时,可能由于系统资源管控等原因导致应用关闭、进程退出,应用直接退出可能会导致用户数据丢失。如果应用在UIAbilityContext中启用了UIAbility备份恢复功能,并对临时数据进行保存,则可以在应用退出后的下一次启动时恢复先前的状态和数据(包括应用的页面栈以及onSaveState接口中保存的数据),从而保证用户体验的连贯性。

说明:

应用正常关闭时,不会触发UIAbility备份流程。应用正常启动(例如通过startAbility接口启动或点击图标启动),不触发UIAbility恢复流程。

运行机制
  • UIAbility数据备份:在应用的onBackground生命周期后,系统自动调用onSaveState进行备份。
  • UIAbility数据恢复:恢复的Want数据可以在应用的onCreate生命周期中获取,页面栈数据在应用的onWindowStageCreate生命周期中恢复。
约束限制
  • UIAbility备份恢复支持多实例,备份数据保存7天,以文件的形式存储在应用的沙箱路径中。

  • 备份数据以WantParams形式存储,由于序列化大小限制,支持的最大数据量为200KB。

  • 重启设备不支持还原备份。UIExtensionAbility不支持备份恢复。

接口说明

UIAbility备份恢复接口由UIAbilityContext模块提供,开发者可以通过在UIAbility中通过this.context直接调用,

接口名称说明
setRestoreEnabled(enabled: boolean): void设置当UIAbility从后台切换回时是否启用恢复。

setRestoreEnabled: 需要在应用初始化阶段调用(onForeground前),比如UIAbility的onCreate调用。

开发步骤

开发者需要在应用模块初始化时启用UIAbility备份恢复功能。

import { UIAbility } from '@kit.AbilityKit';export default class EntryAbility extends UIAbility {onCreate() {console.info("[Demo] EntryAbility onCreate");this.context.setRestoreEnabled(true);}
}

开发者主动保存数据,在UIAbility启动时恢复。

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {console.info("[Demo] EntryAbility onCreate");this.context.setRestoreEnabled(true);if (want && want.parameters) {let recoveryMyData = want.parameters["myData"];}}onSaveState(state:AbilityConstant.StateType, wantParams: Record<string, Object>) {// Ability has called to save app dataconsole.log("[Demo] EntryAbility onSaveState");wantParams["myData"] = "my1234567";return AbilityConstant.OnSaveResult.ALL_AGREE;}
}

4.获取应用异常退出原因

当应用异常退出后再次启动时,开发者往往需要获取上次异常退出的具体原因和当时的应用状态信息,比如应用内存占用的rss、pss值、上次应用退出的时间等等。通过UIAbility和UIExtensionAbility的OnCreate生命周期函数中的launchParam参数,开发者可以获取到相关信息,并将其应用于应用体验的分析改进,从而调整业务逻辑、提高应用的存活率。
仅UIAbility和UIExtensionAbility支持获取上次的退出原因。

接口说明
接口名描述
LaunchParam启动参数。此接口的lastExitReason、lastExitMessage、lastExitDetailInfo成员记录Ability上次异常退出的信息。
LastExitDetailInfo最后退出时的进程状态和详细原因。
开发步骤
  1. 获取UIAbility上次退出的原因。

    在UIAbility类的OnCreate成员函数的launchParam参数中读取Ability上次退出的信息。

    import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit';const MAX_RSS_THRESHOLD: number = 100000;
    const MAX_PSS_THRESHOLD: number = 100000;function doSomething() {console.log('do Something');
    }function doAnotherThing() {console.log('do Another Thing');
    }class MyAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {// 获取退出原因let reason: number = launchParam.lastExitReason;let subReason: number = -1;if (launchParam.lastExitDetailInfo) {subReason = launchParam.lastExitDetailInfo.exitSubReason;}let exitMsg: string = launchParam.lastExitMessage;if (launchParam.lastExitDetailInfo) {// 获取Ability上次退出时所在进程的信息let pid = launchParam.lastExitDetailInfo.pid;let processName: string = launchParam.lastExitDetailInfo.processName;let rss: number = launchParam.lastExitDetailInfo.rss;let pss: number = launchParam.lastExitDetailInfo.pss;// 其他信息let uid: number = launchParam.lastExitDetailInfo.uid;let timestamp: number = launchParam.lastExitDetailInfo.timestamp;}}
    }
    
  2. 根据上次退出的信息做相应的业务处理。

    • 对于不同的退出原因,开发者可以增加不同的处理逻辑,例如:
    if (reason === AbilityConstant.LastExitReason.APP_FREEZE) {// Ability上次因无响应而退出,此处可增加处理逻辑。doSomething();
    } else if (reason === AbilityConstant.LastExitReason.SIGNAL && subReason === 9) {// Ability上次所在进程因kill -9信号而退出,此处可增加处理逻辑。doAnotherThing();
    } else if (reason === AbilityConstant.LastExitReason.RESOURCE_CONTROL) {// Ability上次因rss管控而退出,此处可实现处理逻辑,最简单的就是打印出来。console.log('The ability has exit last because the rss control,the lastExitReason is '+  reason + ', subReason is ' + subReason + ', lastExitMessage is ' + exitMsg);
    }
    
    • 根据进程信息感知应用内存占用异常,例如:
    if (rss > MAX_RSS_THRESHOLD || pss > MAX_PSS_THRESHOLD) {// RSS或PSS值过大,说明内存使用率接近或达到上限,打印告警,或者增加处理逻辑。console.warn('Process ' + processName + '(' + pid + ') memory usage approaches or reaches the upper limit.');
    }
    
    • 根据异常退出时刻的时间戳,明确异常发生的时刻,便于问题定位。
    console.log('App ' + uid + ' terminated at ' + timestamp);
    

AbilityStage 是 OpenHarmony 中Module级生命周期总线,在首次加载 Module 时唯一实例化,负责初始化、环境监听、进程分流、异常恢复等底层工作;搭配 UIAbility 的备份/恢复与退出原因诊断接口,可让应用在被杀->重启->恢复等过程保持用户现场,是开发高可靠多设备应用的隐形引擎

http://www.dtcms.com/a/499066.html

相关文章:

  • 我做了一个免费的 DeepResearch 网站,让科研变得更简单
  • 顺德大良那里做网站好福建省城乡和住房建设厅网站
  • 前端+AI:CSS3(二)
  • go邮件发送——附件与图片显示
  • AI+若依框架(基础篇)
  • 机器学习(2) 线性回归和代价函数
  • 基于Ollama和sentence-transformers,通过RAG实现问答式定制化回复
  • Sentinel:阿里云高并发流量控制
  • 从技术到商业:电商返利平台的核心指标设计(GMV、佣金率、留存率)与技术支撑体系
  • ShardingSphere 源码解析之分片引擎(下)
  • winxp下做网站网店设计美工培训
  • 【论文学习】大语言模型(LLM)论文
  • 做网站ssl证书必须要吗如何黑掉jsp做的网站
  • CLICKHOUSE分布式表初体验
  • 学习周报十八
  • 《Kubernetes 集群搭建全指南:从核心概念到环境部署!》
  • 找工作哪个网站好58同城做网站最简单的
  • 携程网站用js怎么做淄博哪家网络公司做网站好
  • Linux Shell 正则表达式中的 POSIX 字符集:用法与实战
  • MQTT协议,EMQX自建服务器
  • 力扣1287. 有序数组中出现次数超过25%的元素
  • Linux网络与路由配置完全指南
  • 【高并发服务器】六、日志宏的实现
  • 什么是网络割接
  • 中山网站建设文化报价个人网站设计结构图
  • 专业简历制作网站推荐渭南网站建设网站排名优化
  • Electron学习(一):创建第一个应用并打包成功
  • EF Core FromExpression 方法
  • 工厂方法模式
  • 做装机u盘那个网站好市桥做网站