harmonyOS的Ability是什么(一)FA的Page跳转和迁移
1.Ability是什么?
ability是能力的意思
也是HarmonyOS应用程序能力的抽象,功能的意思。
Ability是应用程序的基础单元,一个应用程序可以有多个能力(Ability)。
简单来说应用程序通过Ability为单元来表达功能
2.Ability分为两种类型
FA(feature ability)
PA(patical ability)
每种类型有各自的模板。
FA(又叫元程序)有UI界面可见,PA(又叫元服务)无UI界面。
FA只支持page模板,一个page实例(Page Ability)可以包含一组页面(页面用AbilitySlice实例表示)
PA支持service和data模板,即ServiceAbility(用于后台任务)和DataAbility(用于数据访问)。
使用Ability需要在config.json中注册:用“type”类型指定模块类型(page,service,data)。
{ "module": { ... "abilities": [ { ... "type": "page" ... } ] ... } ... }
3.Page Ability与AbilitySlice
后面内容Page Ability有时候用Page表示。
一个page实例可以有多个AbilitySlice实例(每个AbilitySlice表示单个页面和逻辑)。
Page进入前台默认显示的AbilitySlice需要通过SetMainRoute()设置。
跳转到特定的AbilitySlice:
先要addActionRoute()设置路由规则(即用action来表示对应AbilitySlice),然后在intent中指定action跳转。
public class MyAbility extends Ability { @Override public void onStart(Intent intent) { super.onStart(intent); // set the main route setMainRoute(MainSlice.class.getName()); // set the action route addActionRoute("action.pay", PaySlice.class.getName()); addActionRoute("action.scan", ScanSlice.class.getName()); } }
addActionRoute()添加的的动作(action)需要在config.json中注册:
{ "module": { "abilities": [ { "skills":[ { "actions":[ "action.pay", "action.scan" ] } ] ... } ] ... } ... }
总结:
不管是FA还是Page Ability都概念名称,上面已经说了。
用代码来具体表达他们就是:Ability和AbilitySlice类。
Ability类是Page Ability的表达,即可以拥有多个页面的能力类。
AbilitySlice类是页面的表达。
4.Page Ability的生命周期。
系统管理和用户操作引起的生命周期状态的改变可以用以下回调函数来体现。
主要有四种状态六种回调方法
1.initial:初始状态,Page Ability实例化之前的状态。 2.inactive:待激活状态,Page处于前台但不能交互。 3.active:活动状态,处于前台且能交互。 4.background:后台状态,Page不可见但在内存。 onStart():首次实例化Page对象触发回调,整个生命周期触发一次。 触发前为初始状态触发后为待激活状态, 必须重写配置默认显示的AbilitySlice。 onActive()和onInactive()一般成对出现。 首次实例化Page进入前台触发onActive(),回调后由待激活状态进入活动状态。 Page失去焦点(别的Page遮挡但可见或者进入后台)触发onInactive(),回调后由活动状态进入待激活状态。 Page再次获得焦点触发onActive(),回调后由待激活状态进入活动状态。 onBackground():Page不可见触发,触发后进入后台状态。(从可见激活状态到后台状态必然存在待激活状态过渡) onForeground():处于后台的Page进入前台触发,回调后由后台状态变成待激活状态。 onStop():系统要销毁Page触发: 1.任务管理器关闭Page。 2.调用Page的terminateAbility()退出应用。 3.配置变更暂时销毁和重建Page。 4.资源回收后台状态的Page。
5.Page的AbilitySlice生命周期。
5.1.AbilitySlice同步Page的生命周期变化:
AbilitySlice是Page的组成部分并且依托于Page具有相同生命周期状态和回调方法。
Page生命周期发生变化处于前台的AbilitySlice状态同步变化,Page销毁时前后台的AbilitySlice也都销毁。
5.2.此外AbilitySlice还有独立于Page生命周期变化外的情况:
同一Page内的AbilitySlice之间的导航跳转,Page处于活动状态不变的,AbilitySlice状态发生变化。
AbilitySlice作为实际页面的承载,必须在onStart()中设置页面(setUIContent设置布局文件)
@Override protected void onStart(Intent intent) { super.onStart(intent); setUIContent(ResourceTable.Layout_main_layout); }
同一Page下AAbilitySlice导航到BAbilitySlice生命周期变化:
1.AAbilitySlice由激活状态变为待激活状态。 2.BAbilitySlice由初始状态到待激活状态到活动状态(B首次实例化不在后台情况) 3.AAbilitySlice由待激活状态到后台状态。 回调方法顺序: AAbilitySlice的onInactive()-> BAbilitySlice的onStart()->onActive()-> AAbilitySlice的onBackground()
6.导航方法:
6.1.同一Page下:
一般导航跳转用present():
@Override protected void onStart(Intent intent) { ... Button button = ...; button.setClickedListener(listener -> present(new TargetSlice(), new Intent())); ... }
导航需要返回数据用presentForResult()跳转,用onResult接收数据:
int requestCode = positiveInteger; // Any positive integer. @Override protected void onStart(Intent intent) { ... Button button = ...; button.setClickedListener( listener -> presentForResult(new TargetSlice(), new Intent(), positiveInteger)); ... } @Override protected void onResult(int requestCode, Intent resultIntent) { if (requestCode == positiveInteger) { // Process resultIntent here. } }
每个AbilitySlice实例都是唯一的放在所属Page的栈中。
处于的前台的在栈顶,
实例化前先到栈中查找,
没有新建放入栈,有的话,弹出其上面的实例(即销毁)让其处于栈顶。
6.2.不同Page跳转:
最终跳转的目的其实还是Page下对应的AbilitySlice.
AbilitySlice以Action的形式暴露。
一般跳转用:
startAbility();
需要返回数据跳转:
startAbilityForResult();
onAbilityResult();
不同Page跳转上面是知道目的Ability名称,还有不知道名称的情况,在下面讲解Intent时候细说(利用operation属性)。
7.Page跨设备迁移
同一用户的不同设备支持page的迁移。
设备A迁移到设备B: 1.设备A发起迁移请求 2.鸿蒙系统处理迁移任务使用保存数据的回调方法保存数据 3.鸿蒙系统在设备B启动同一个Page并使用恢复数据方法 体现了分布式系统的效果
一个应用可能有多个Page,需要迁移的Page必须实现IAbilityContinuation接口,此Page下所有AbilitySlice也需要实现该接口。
IAbilityContinuation接口的方法:
onStartContinuation()
Page请求迁移后,系统首先回调此方法,
开发者可以在此回调中决策当前是否可以执行迁移,
比如,弹框让用户确认是否开始迁移。
onSaveData()
如果onStartContinuation()返回true,则系统回调此方法,
开发者在此回调中保存必须传递到另外设备上以便恢复Page状态的数据。
onRestoreData()
源侧设备上Page完成保存数据后,系统在目标侧设备上回调此方法,
开发者在此回调中接受用于恢复Page状态的数据。
注意,在目标侧设备上的Page会重新启动其生命周期,
无论其启动模式如何配置。
且系统回调此方法的时机在onStart()之前。
onCompleteContinuation()
目标侧设备上恢复数据一旦完成,
系统就会在源侧设备上回调Page的此方法,
以便通知应用迁移流程已结束。
开发者可以在此检查迁移结果是否成功,
并在此处理迁移结束的动作,
例如,应用可以在迁移完成后终止自身生命周期。
onFailedContinuation()
迁移过程中发生异常,系统会在发起端设备上回调FA的此方法,
以便通知应用迁移流程发生的异常。
并不是所有异常都会回调FA此方法,
仅局限于该接口枚举的异常。
开发者可以在此检查异常信息,并在此处理迁移异常发生后的动作,
例如,应用可以提醒用户此时发生的异常信息。
该接口从API Version 6开始提供,目前为Beta版本。
onRemoteTerminated()
如果开发者使用continueAbilityReversibly()而不是continueAbility(),
则此后可以在源侧设备上使用reverseContinueAbility()进行回迁。
这种场景下,相当于同一个Page(的两个实例)同时在两个设备上运行,
迁移完成后,如果目标侧设备上Page因任何原因终止,
则源侧Page通过此回调接收终止通知。
7.1.请求迁移
实现IAbilityContinuation的Page可以在其生命周期内,
调用continueAbility()或continueAbilityReversibly()请求迁移。
两者的区别是,通过后者发起的迁移此后可以进行回迁。
try { continueAbility(); } catch (IllegalStateException e) { // Maybe another continuation in progress. ... } 以Page从设备A迁移到设备B为例,详细的流程如下: 1.设备A上的Page请求迁移。 2.系统回调设备A上Page 及其AbilitySlice栈中所有AbilitySlice实例的IAbilityContinuation.onStartContinuation()方法, 以确认当前是否可以立即迁移。 3.如果可以立即迁移, 则系统回调设备A上Page及其AbilitySlice栈中所有AbilitySlice实例的IAbilityContinuation.onSaveData()方法, 以便保存迁移后恢复状态必须的数据。 4.如果保存数据成功,则系统在设备B上启动同一个Page,并恢复AbilitySlice栈, 然后回调IAbilityContinuation.onRestoreData()方法,传递此前保存的数据; 此后设备B上此Page从onStart()开始其生命周期回调。 5.系统回调设备A上Page及其AbilitySlice栈中所有AbilitySlice实例的IAbilityContinuation.onCompleteContinuation()方法, 通知数据恢复成功与否。 6.迁移过程中发生异常, 系统回调设备A上Page及其AbilitySlice栈中所有AbilitySlice实例的IAbilityContinuation.onFailedContinuation()方法, 通知迁移过程中发生异常,并不是所有异常都会回调FA此方法,仅局限于该接口枚举的异常。
7.2.请求回迁
使用continueAbilityReversibly()请求迁移并完成后,源侧设备上已迁移的Page可以发起回迁,以便使用户活动重新回到此设备。
try { reverseContinueAbility(); } catch (IllegalStateException e) { // Maybe another continuation in progress. ... } 以Page从设备A迁移到设备B后并请求回迁为例,详细的流程如下: 1.设备A上的Page请求回迁。 2.系统回调设备B上Page及其AbilitySlice栈中 所有AbilitySlice实例的IAbilityContinuation.onStartContinuation()方法, 以确认当前是否可以立即迁移。 3.如果可以立即迁移,则系统回调设备B上Page及其AbilitySlice栈中 所有AbilitySlice实例的IAbilityContinuation.onSaveData()方法, 以便保存回迁后恢复状态必须的数据。 4.如果保存数据成功,则系统在设备A上Page恢复AbilitySlice栈, 然后回调IAbilityContinuation.onRestoreData()方法, 传递此前保存的数据。 如果数据恢复成功,则系统终止设备B上Page的生命周期。