欲开发鸿蒙应用,须先搞懂 Ability。
Ability是什么
官方定义Ability 是应用所具备能力的抽象,也是应用程序的重要组成部分。
它是可见的,承载一个业务可视化界面;亦可为隐藏的,在背后默默为你干脏活;又能在多应用间架起数据访问的桥梁,方便数据沟通。
鸿蒙应用是以 Ability 为单位进行部署,开发者通过继承 Ability 类来实现应用所需能力。
如果从安卓 API 能力角度上看,鸿蒙OS的 Ability 提供的能力囊括了 Activity、Service、ContentProvider。
Ability 根据是否可交互划分为 Feature和Particle两种类型。
不同类型会根据其支持模板可再细分:
- Feature 目前仅支持Page模板,用于提供与用户交互的能力,包括写视图组件等。
- Particle 支持Service模板和Data模板,前者用于提供后台运行任务的能力,后者对外提供数据访问的能力。
怎么使用 Ability
只能直接继承来实现不同模板能力,而不同模板实现的子类需要主动选择覆盖对应方法。
比如可视化的 Page 模板关注的是页面生命周期变化,所以重载的方法主要是生命周期变化的回调方法。
而 Service 模板更关注的是服务的连接与断开,重载的方法则与 Page 模板不一样。
说实话这样的设计并不好,针对模板分类封装 Ability 显然更友好。
我们以可视化 Page 模板作为例子展开。
编写一个闪屏页面
public class SplashScreenAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
//视图片,后面会有讲到
super.setMainRoute(SplashScreenAbilitySlice.class.getName());
}
}
可以看到我们重载的 onStart 方法。
onStart只是系统首次创建 Page 时的回调,对于页面的生命周期的状态转化及对应回调可见下图。
![file]()
下面针对核心方法做简单阐述:
- onStart,当系统首次创建 Page 实例时触发该回调。对于一个 Page 实例,该回调在其生命周期过程中仅触发一次, 此后进入 INACTIVE 状态。开发者必须重写该方法,并在此配置默认展示的 AbilitySlice。
- onActive,Page 会在进入 INACTIVE 状态后来到前台,然后系统调用此回调。在此之后进入 ACTIVE 状态,该状态是应用与用户交互的状态。
- onInactive,Page 失去焦点时系统将调用此回调,此后 Page 进入 INACTIVE 状态。
- onBackground,如果 Page 不再对用户可见,系统将调用此回调通知开发者用户进行相应的资源释放,此后 Page 进入 BACKGROUND 状态。
- onForeground,处于 BACKGROUND 状态的 Page 仍然驻留在内存中,当重新回到前台时(比如用户重新导航到此 Page ),系统将先调用 onForeground() 回调通知开发者,而后 Page 的生命周期状态回到 INACTIVE 状态。开发者应当在此回调中重新申请在 onBackground() 中释放的资源,最后 Page 的生命周期状态进一步回到 ACTIVE 状态,系统将通过 onActive() 回调通知开发者用户。
- onStop,系统将要销毁 Page 时,将会触发此回调函数,通知用户进行系统资源的释放。
对比安卓 Activity 生命周期回调(左鸿蒙右安卓)
onStart() --> onCreate()
onActive() --> onResume()
onInactive() --> onPause()
onBackground() --> onStop()
onForeground() --> onRestart()
onStop() --> onDestroy()
生命周期变化规律的回调看起来确实很像 Activity场景,但在视图编写流程上却有些差异。
例子代码中出现的 SplashScreenAbilitySlice 实际上才是真正承载视图逻辑的类。
其继承的是 AbilitySlice 类,通过 supe#setMainRoute 的方法来导航到真正视图界面。
那么 AbilitySlice 是什么呢?
官方定义为AbilitySlice 作为 Page 的组成单元,其生命周期是依托于其所属 Page 生命周期。
AbilitySlice 和 Page 具有相同的生命周期状态和同名的回调,当 Page 生命周期发生变化时,它的 AbilitySlice 也会发生相同的生命周期变化。
|---AbilityContext
| |---Ability
| |---AbilitySlice //Page组成元素
都继承自 AbilityContext,实现的方法大致相同。
只是 AbilitySlice 比 Page 多了一些生命周期变化,这些变化发生在同一 Page 中的多个 AbilitySlice 之间导航时,但此时 Page 的生命周期状态并不会改变。
AbilitySlice 跟 Fragment 有点像,只是 Page 必须通过设置 AbilitySlice 展示页面视图。
以下是 SplashScreenAbilitySlice 简单实现。
public class SplashScreenAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_splash_screen_layout);
}
}
上述代码通过调用 setUIContent 设置布局。
Demo 实现一个完整的闪屏逻辑,效果如下,感兴趣可到 Github 查看实现。
![file]()
对于 Service 模板及 Data 模板,则直接覆盖对应方法即可,这部分暂不过多描述,细节可到 HarmonyOS Developer 开发文档 中查阅。
既然 Ability 划分多种模板,那么应用如何区分这些模板呢?
区分 Ability 模板
在《Harmony系列之 工程结构与应用配置的理解》一文中我们有讲过在每个模块都会有一个 config.json 配置文件。
而这个文件的 module 节点中需要申明应用所需要用到的 Ability。
"abilities": [
{
"orientation": "portrait",
"name": "com.effective.harmony.study.ability.page.SplashScreenAbility",
"type": "page",
},
{
"name": "com.effective.harmony.study.ability.service.ServiceAbility",
"type": "service",
}
]
如上图,申明了 SplashScreenAbility 为 Page模板,ServiceAbility 为 Service模板。
这一点和安卓应用中 AndroidManifest.xml 需要申明四大组件逻辑是一致的。
虽然目前官方 SDK 源码并没有开源,但在 Framework 层应该是对应类型进行分类,并在各自模板场景下做方法映射调用。
初探Ability至此,但我更好奇的是 Framework 层的实现。
遗憾的是,目前 SDK 目前还没有开源,API 也没有注释呐。