【鸿蒙中级】
文章目录
在开发态新建一个项目时,ide默认生成一个持有UIAbility组件的model作为应用的主模块,该模块用于实现应用的入口界面和主特性功能,对于UIAbility组件,系统提供了具体的UIAbility类承载,支持面向对象的开发方式,如下图所示,系统默认生成的EntryAbility类继承了UIAbility类

各类型的ExtensionAbility组件均由相应的系统服务统一管理,例如InputMethodExtensionAbility组件由输入法管理服务统一管理。在ide中,支持选中module后创建不同类型的ExtensionAbility组件文件,如图所示:

包含ExtensionAbility组件或者UIAbility组件的module可以单独运行,该类型module运行时,会编译生成一个.hap文件,一个app可以包含一个或多个HAP,当HAP中的代码首次被加载到进程中时,也就是module初始化时,系统首先会创建一个AbilityStage实例,AbilityStage是一个module级别的组件容器,可以管理module中的ExtensionAbility组件和UIAbility组件

在开发时,一个项目可能包含一个或多个可以单独运行的module,对应到运行期,一个应用即一个application,就可能包含一个或多个AbilityStage,对应到编译期,一个app可能包含一个或多个HAP,在运行期,每个AbilityStage持有该module上定义的,ExtensionAbility组件和UIAbility组件,当UIAbility组件首次启动时,系统会为UIAbility组件创建实例,并将该实例与持有他的AbilityStage示例关联,开发者可以通过AbilityStage获取该UIAbility实例的运行时信息,UIAbility实例创建后,系统为该实例创建一个WindowStage实例,并一对一绑定,windowstage实例提供了应用进程类窗口管理器的作用,他持有一个主窗口,该主窗口为arkui提供了绘制区域,并管理多个arkui页面,在运行期,系统为application、AbilityStage、UIAbility组件和ExtensionAbility组件分别提供了对应的上下文环境,分别是ApplicationContext、AbilityStageContext、UIAbilityContext、ExtensionAbilityContext,开发者可以通过上下文环境调用各种资源和能力。运行期和编译期的基本概念中,最重要的就是UIAbility组件,UIAbility组件的核心是生命周期,当用户启动、使用、退出应用时,应用的UIAbility实例会在其生命周期的不同状态之间转换

在应用程序框架中,UIAbility组件和WindowStage各自拥有一套生命周期,在设备上首次启动某个UIAbility组件时,AbilityStage、UIAbility组件和WindowStage的生命周期执行顺序如图所示,系统首先创建持有该UIAbility组件的AbilityStage实例,创建成功后,执行其onCreate生命周期回调函数,开发者可以通过重写该函数,再进行一些module级别的资源初始化或临时全局共享数据的设置工作,接下来,系统会为该UIAbility组件创建实例,创建成功后执行其onCreate生命周期回调函数,可以在该函数中初始化业务逻辑,例如定义变量、资源预加载等,用于后续的ui展示,onCreate函数执行完成后,系统将为UIAbility实例创建一个WindowStage实例,创建成功后,执行UIAbility实例的onWindowStageCreate回调函数,可以通过该函数获取主窗口信息、设置ui加载页面,以及监听WindowStage的生命周期变化,相应的,在UIAbility实例销毁之前,将先进入UIAbility实例的onWindowStageDestroy回调函数,开发者可以在该函数中释放ui界面资源,例如,在onWindowStageDestroy函数中注销WindowStage的事件

可以看到应用组件和窗口的生命周期是松耦合的,这种设计模式有如下好处:
- 业务逻辑和ui逻辑分离,开发者可以在UIAbility组件中处理与页面无关的业务逻辑,如打开蓝牙、链接数据库等,在WindowStage持有的窗口上,通过arkui处理界面相关的业务逻辑
- 便于系统对应用组件进行裁剪,例如,对于无屏设备,系统在运行应用时不会创建窗口模块,有利于减少系统rom空间占用,
- 在多设备如桌面设备和移动设备上,应用组件可使用同一套生命周期,应用运行时,系统会自动判断设备,并根据不同设备的窗口形态变换,执行不同的生命周期变化流程,以在单窗口形态上和多窗口形态上任务切换的场景为例,在设备上,一个UIAbility实例对应于任务视图的一个任务,在单窗口形态如移动设备上,当用户从任务一切换到任务二时,对于任务一,会触发其WindowStage的inActive失焦和hidden隐藏生命周期,继而触发其UIAbility实例的background生命周期,对于任务二,会触发其WindowStage的shown显示和active聚焦生命周期,进而触发其UIAbility实例的foreground生命周期,在多窗口形态,如2in1上,当用户从任务一切换到任务二时,对于任务一,会触发其WindowStage的inActive失焦生命周期,不会触发其UIAbility实例的生命周期,对于任务二,触发WindowStage的active聚焦生命周期,不会触发其UIAbility实例的生命周期
AbilityStage最主要的能力是初始化模块,以及对以指定实例模式启动的UIAbility组件进行匹配处理,目前系统提供了4个回调函数供开发者使用其能力 - onCreate:开发者可在此函数中进行模块初始化操作,如资源预加载、线程创建等
- onAcceptWant:开发者可在此函数中对指定实例模式启动的UIAbility实例返回其唯一的key值,用于系统判断该实例是否已经存在
- onConfigurationUpdate:开发者可在此函数中接收到系统最新的全局配置信息,并按需进行业务逻辑处理,例如可以在该函数中获取系统最新的深浅色模式,并根据当前深浅色模式对界面进行主题化定制
- onMemoryLevel:应用被切换到后台时,系统会将后台的应用保留在缓存中,即使应用处于缓存中也会影响系统整体的性能,当系统资源不足时,系统会通过多种方式从应用中回收内存,必要时会完全停止应用,从而释放内存用于执行关键任务,为了进一步保持系统内存的平衡,避免系统停止用户的应用进程,可以在此函数中订阅系统内存的变化情况,释放不必要的资源
UIAbility组件启动模式 - 单实例启动模式:系统每次启动UIAbility组件时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。同一UIAbility组件在系统中只存在唯一一个UIAbility实例,即在任务视图中只存在一个该类型的任务
- 多实例启动模式:在任务视图中可以看到有多个该类型的任务,如在2in1设备上的浏览器应用,每次打开浏览器都会新创建一个浏览器任务窗口,
- 指定实例启动模式:常用于文档应用,每次新建文档时需要新建一个UIAbility实例,每次打开一个已保存的文档时,需要拉起同一个UIAbility实例
当调用方通过startAbility()启动UIAbility组件时,系统启动被调用的UIAbility组件,此时系统判断被调用的UIAbility组件是否为冷启动,通常我们将首次启动称为冷启动,非首次启动为热启动,若是冷启动,系统新建该UIAbility组件的实例,并执行其onCreate()生命周期回调函数,之后,系统将创建一个与该UIAbility实例一一对应的WindowStage实例,创建成功后,执行该UIAbility实例的onWindowStageCreate函数,接着,UIAbility实例将进入前台生命周期,并执行其onForeground生命周期回调函数,若被调用的UIAbility组件不是冷启动,系统将执行已经存在的该类型UIAbility实例的onNewWant回调函数,可以在该函数中解析从调用方传递过来的want参数并进行业务逻辑处理,之后,UIAbility实例进入前台生命周期,并执行其onForeground生命周期回调函数
当调用方通过startAbility()启动UIAbility组件时,系统启动被调用的UIAbility组件,在启动被调用的UIAbility组件之前,系统先触发持有被调用的UIAbility组件的AbilityStage的onAcceptWant()回调函数,该函数会解析调用方传递的want信息,并返回被调用的UIAbility实例的唯一key值,系统根据返回的唯一key值,判断当前进程中该key值对应的UIAbility实例是否已经存在,若存在,则系统执行该UIAbility实例的onNewWant()回调函数,之后UIAbility实例进入前台生命周期,并执行其onForeground生命周期回调函数,若不存在,则系统新建被调用的UIAbility组件实例,并执行其onCreate()生命周期回调函数,随后创建对应的WindowStage实例,并执行该UIAbility实例的onWindowStageCreate函数,最后,UIAbility实例进入前台生命周期,并执行其onForeground生命周期回调函数
want是对象间信息传递的载体,用于在应用组件间传递信息,其使用场景之一是作为startAbility的参数,当UIAbilityA需要启动并需要传递一些数据给UIAbilityB时,want可以作为一个载体将数据传递给UIAbilityB,want中可以包含指定的启动目标以及启动时需要携带的相关数据,如bundleName字段和abilityName字段,分别表示目标Ability所在应用的包名和Ability名