『HarmonyOS』Page与Slice的生命周期

👨‍🎓作者简介:一位喜欢写作,计科专业大二菜鸟

🏡个人主页:starry陆离
📚订阅专栏:『HarmonyOS』

🍁每日推荐:牛客网-面试神器
在这里插入图片描述
如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦

@TOC

系统管理或用户操作等行为均会引起Page实例在其生命周期的不同状态之间进行转换。Ability类提供的回调机制能够让Page及时感知外界变化,从而正确地应对状态变化(比如释放资源),这有助于提升应用的性能和稳健性。

生命周期(百度百科)

生命周期就是指一个对象的生老病死。

​ 生命周期(Life Cycle)的概念应用很广泛,特别是在政治、经济、环境、技术、社会等诸多领域经常出现,其基本涵义可以通俗地理解为 “从摇篮到坟墓”(Cradle-to-Grave的整个过程。对于某个产品而言,就是从自然中来回到自然中去的全过程,也就是既包括制造产品所需要的原材料的采集、加工等生产过程,也包括产品贮存、运输等流通过程,还包括产品的使用过程以及产品报废或处置等废弃回到自然过程,这个过程构成了一个完整的产品的生命周期。

1.Page的生命周期

Page Ability是主要负责页面交互的,所以Page有几个状态:可见,可交互,不可见,销毁等等。每一个状态,都有一个生命周期函数和它对应。Page生命周期的不同状态转换及其对应的回调如下图所示:

image-20220707160055890

1.onStart()

当系统首次创建Page实例时,触发该回调。对于一个Page实例,该回调在其生命周期过程中仅触发一次,Page在该逻辑后将进入INACTIVE状态。开发者必须重写该方法,并在此配置默认展示的AbilitySlice。

@Override
public void onStart(Intent intent) {
    super.onStart(intent);
    super.setMainRoute(MainAbilitySlice.class.getName());
}

2.onActive()

Page会在进入INACTIVE状态后来到前台,然后系统调用此回调。Page在此之后进入ACTIVE状态,该状态是应用与用户交互的状态Page将保持在此状态,除非某类事件发生导致Page失去焦点,比如用户点击返回键或导航到其他Page。当此类事件发生时,会触发Page回到INACTIVE状态,系统将调用onInactive()回调。此后,Page可能重新回到ACTIVE状态,系统将再次调用onActive()回调。因此,开发者通常需要成对实现onActive()和onInactive(),并在onActive()中获取在onInactive()中被释放的资源。

3.onInactive()
当Page失去焦点时,系统将调用此回调,此后Page进入INACTIVE状态。开发者可以在此回调中实现Page失去焦点时应表现的恰当行为。

4.onBackground()
如果Page不再对用户可见,系统将调用此回调通知开发者用户进行相应的资源释放,此后Page进入BACKGROUND状态。开发者应该在此回调中释放Page不可见时无用的资源,或在此回调中执行较为耗时的状态保存操作。

5.onForeground()
处于BACKGROUND状态的Page仍然驻留在内存中,当重新回到前台时(重新导航到此Page),系统将先调用onForeground()回调通知开发者,而后Page的生命周期状态回到INACTIVE状态。开发者应当在此回调中重新申请在onBackground()中释放的资源,最后Page的生命周期状态进一步回到ACTIVE状态,系统将通过onActive()回调通知开发者用户。

6.onStop()

系统将要销毁Page时,将会触发此回调函数,通知用户进行系统资源的释放。销毁Page的可能原因包括以下几个方面:

  • 用户通过系统管理能力关闭指定Page,例如使用任务管理器关闭Page。
  • 用户行为触发Page的terminateAbility()方法调用,例如使用应用的退出功能。
  • 配置变更导致系统暂时销毁Page并重建。
  • 系统出于资源管理目的,自动触发对处于BACKGROUND状态Page的销毁。

2.AbilitySlice生命周期

AbilitySlice作为Page的组成单元,其生命周期是依托于其所属Page生命周期的AbilitySlice和Page具有相同的生命周期状态和同名的回调,当Page生命周期发生变化时,它的AbilitySlice也会发生相同的生命周期变化。此外,AbilitySlice还具有独立于Page的生命周期变化,这发生在同一Page中的AbilitySlice之间导航时,此时Page的生命周期状态不会改变。

AbilitySlice生命周期回调与Page的相应回调类似,因此不再赘述。由于AbilitySlice承载具体的页面,开发者必须重写AbilitySlice的onStart()回调,并在此方法中通过setUIContent()方法设置页面,如下所示:

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);

        setUIContent(ResourceTable.Layout_main_layout);
    }

AbilitySlice实例创建和管理通常由应用负责,系统仅在特定情况下会创建AbilitySlice实例。例如,通过导航启动某个AbilitySlice时,是由系统负责实例化;但是在同一个Page中不同的AbilitySlice间导航时则由应用负责实例化。

3.Page与AbilitySlice生命周期关联

当AbilitySlice处于前台且具有焦点时,其生命周期状态随着所属Page的生命周期状态的变化而变化。

当一个Page拥有多个AbilitySlice时,例如:MyAbility下有FooAbilitySlice和BarAbilitySlice,当前FooAbilitySlice处于前台并获得焦点,并即将导航到BarAbilitySlice,在此期间的生命周期状态变化顺序为:

  1. FooAbilitySlice从ACTIVE状态变为INACTIVE状态
  2. BarAbilitySlice则从INITIAL状态首先变为INACTIVE状态,然后变为ACTIVE状态(假定此前BarAbilitySlice未曾启动)。
  3. FooAbilitySlice从INACTIVE状态变为BACKGROUND状态

对应两个slice的生命周期方法回调顺序为:

FooAbilitySlice.onInactive() --> BarAbilitySlice.onStart() --> BarAbilitySlice.onActive() --> FooAbilitySlice.onBackground()

在整个流程中,MyAbility始终处于ACTIVE状态。但是,当Page被系统销毁时,其所有已实例化的AbilitySlice将联动销毁,而不仅是处于前台的AbilitySlice。

4.Page与AbilitySlice生命周期的例子

​ 为了更好地理解Page与AbilitySlice的生命周期,我们将创建一个PageAndAbilitySliceLifeCycle的应用作为演示。

此应用中包含两个Slice,MainAbilitySlicePayAbilitySlice分别代表主页界面和支付界面

我们运行项目首先创建主页界面,主页界面的onStart()onActive()方法分别调用,MainAbilitySlice处于与用户交互的状态

image-20220801160010848

用户点击跳转到支付界面,首先MainAbilitySlice界面失去焦点,进入onInactive()状态;马上创建了一个PayAbilitySlice界面,onStart()方法被调用,紧接着PayAbilitySlice进入onActive()状态,此时用户可见的是支付界面,而MainAbilitySlice调用onBackground()方法,此Slice不再对用户可见,通知开发者释放资源

image-20220801160425873

在这个demo中,系统没有销毁MainAbilitySlice,而是将其存入幕后不再让用户可见,因为我们可以看到日志台并没有打印onStop()方法;也就是说我们每点击一次跳转,就创建一个新的Slice(调用onStart()方法)。

image-20220801161813919

这一次我们不点击跳转了,而是点击虚拟机上的返回按键,可以看到这一次打印了五条日志。首先PayAbilitySlice失去焦点,进入onInactive状态,而MainAbilitySlice从后台资源中重新回到前台,(这里也再次证明了我们的MainAbilitySlice是没有被销毁的)然后就如用户可见的onActive状态;而用户不可见的PayAbilitySlice调用onBackground方法进入后台资源中,最终被onStop()方法销毁,至此PayAbilitySlice度过了它的一个生命周期

5.MainAbilitySlice

package com.hnucm.hmos0501_pageandabilityslicelifecycle.slice;

import com.hnucm.hmos0501_pageandabilityslicelifecycle.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class MainAbilitySlice extends AbilitySlice {

    static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MainAbilitySlice"); //MY_MODULE=0x00201
    @Override
    public void onStart(Intent intent) {

        HiLog.info(label, "MainAbilitySlice---->onStart");
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        Button toPayBtn=findComponentById(ResourceTable.Id_toPayBtn);
        toPayBtn.setClickedListener(listener-> present(new PayAbilitySlice(),new Intent()));
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        HiLog.info(label, "MainAbilitySlice---->onInactive");
    }

    @Override
    protected void onBackground() {
        super.onBackground();

        HiLog.info(label, "MainAbilitySlice---->onBackground");

    }

    @Override
    protected void onStop() {
        super.onStop();
        HiLog.info(label, "MainAbilitySlice---->onStop");

    }

    @Override
    public void onActive() {
        super.onActive();
        HiLog.info(label,  "MainAbilitySlice---->onActive");
    }
    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(label, "MainAbilitySlice---->onForeground");
    }
}

6.PayAbilitySlice

package com.hnucm.hmos0501_pageandabilityslicelifecycle.slice;

import com.hnucm.hmos0501_pageandabilityslicelifecycle.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class PayAbilitySlice extends AbilitySlice {

    static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00201, "PayAbilitySlice"); //MY_MODULE=0x00201

    @Override
    public void onStart(Intent intent) {

        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_pay);

        HiLog.info(label, "PayAbilitySlice---->onStart");


        Button backMainBtn=findComponentById(ResourceTable.Id_backMainBtn);
        backMainBtn.setClickedListener(listener-> present(new MainAbilitySlice(),new Intent()));
    }

    @Override
    public void onActive() {
        super.onActive();
        HiLog.info(label, "PayAbilitySlice---->onActive");

    }

    @Override
    protected void onInactive() {
        super.onInactive();
        HiLog.info(label, "PayAbilitySlice---->onInactive");

    }

    @Override
    protected void onBackground() {
        super.onBackground();
        HiLog.info(label, "PayAbilitySlice---->onBackground");


    }

    @Override
    protected void onStop() {
        super.onStop();
        HiLog.info(label, "PayAbilitySlice---->onStop");

    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(label, "PayAbilitySlice---->onForeground");

    }
}

🍁每日推荐:牛客网-面试神器
在这里插入图片描述

#华为##鸿蒙#
全部评论
君作之奕文,与同分享,吾甚兴,特来此,与君同悦
点赞 回复 分享
发布于 2022-08-22 17:23 河北

相关推荐

2025-11-07 03:09
深圳大学 C++
实习秋招做的很差,也想总结一下自己的大学生涯吧。不算太摆,但是很迷。0.大学前高考发挥超常,才来到深大计软。大学前暑期基本上都是玩游戏了。接触了python(李笑来)但是没接触到online judge,也没去多了解编程生态、计算机行业。背了背单词,但是没去规划指标如六级,没制定计划不了了之。1.大一军训时去了校ACM培训,当时dev编译器都不会下载。军训期间积极看B站大学c语言课程。力扣,牛客都是知道的,但是没有成为很好的跳板。第二次培训,看不懂cpp的 cin>>,网上搜了也没搞懂,再加上周末跟训得三个多小时,感觉跟不上放弃了。自费报了蓝桥杯,混了省二跟着一些机构课程学习,走的cpp路线。暑假在linux上熟悉vim操作。2.大二朝花夕拾,又去参加ACM训练,跟了一年,寒假都在码 带懒标记的线段树。codeforce和力扣赛都在打打(竞赛还是有趣的)。集训队入队周赛打四场,校赛拿金,面试时表现差,说自己想就业,遂挂。当时四月多,2024华为软件精英挑战赛也在打,拿了80名(前64才有三等奖)。蓝桥杯国二。很多晚上跑步来消磨时间。3.大三上修了深大最强的计算机图形学,408找实习,投简历了说自己只有周末有空,遂没在找。也没看牛客真实行情。寒假随便做了个日志器,属于混过去了。当时接到字节的面试(人生处女面),前一天觉都睡不好,很紧张,手撕做的不好,话都说不利索了。面评脏。大三下找实习,cpp选手,没有很好经历、项目,运气好去了学校附近中厂实习。4.大四现在,貌似对开发不上心?没有好的offer(甚至hot100不会做)其实同届好多同学都拿的不错。还有保研C9的。嗯,考研吧。————对自己行为的分析:a.应试教育+应试家庭教育,我的个性是固执、遵规守矩的。b.还有莫名的孤独,明明有很多朋友,但还是没有很好的内驱力,没有坚定的理想。c.自己没有很好的调研、探索和规划能力。大家也可以锐评一下😊
_Matrice_:差不多的性格,不然不会本科时硬杠cpp(那个时候还没有大模型,啃完一整本primer和习题,还是做不出来什么东西),还找不到方向,相比之下学习一些应用层的同学已经能够参考别人的方法做出实用的应用了。学东西,找实习,感觉更多地是出于和别人比较,而不是自我内驱。不过...正如deft所说,人生不需要他人的建议,所以也没有标准化的路径,在能够自食其力的背景下慢慢找到自己的生活方式吧...。另外面试很多时候看运气、眼缘
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务