关于harmonyos:PageAbility的生命周期

47次阅读

共计 24658 个字符,预计需要花费 62 分钟才能阅读完成。

Page Ability 生命周期

作者:韩茹

公司:程序咖(北京)科技有限公司

鸿蒙巴士专栏作家

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

一、Page 生命周期回调

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

  • onStart()

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

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

    Page 会在进入 INACTIVE 状态起初到前台,而后零碎调用此回调。Page 在此之后进入 ACTIVE 状态,该状态是利用与用户交互的状态。Page 将放弃在此状态,除非某类事件产生导致 Page 失去焦点,比方用户点击返回键或导航到其余 Page。当此类事件产生时,会触发 Page 回到 INACTIVE 状态,零碎将调用 onInactive() 回调。尔后,Page 可能从新回到 ACTIVE 状态,零碎将再次调用 onActive() 回调。因而,开发者通常须要成对实现 onActive() 和 onInactive(),并在 onActive() 中获取在 onInactive() 中被开释的资源。

  • onInactive()

    当 Page 失去焦点时,零碎将调用此回调,尔后 Page 进入 INACTIVE 状态。开发者能够在此回调中实现 Page 失去焦点时应体现的失当行为。

  • onBackground()

    如果 Page 不再对用户可见,零碎将调用此回调告诉开发者用户进行相应的资源开释,尔后 Page 进入 BACKGROUND 状态。开发者应该在此回调中开释 Page 不可见时无用的资源,或在此回调中执行较为耗时的状态保留操作。

  • onForeground()

    处于 BACKGROUND 状态的 Page 依然驻留在内存中,当从新回到前台时(比方用户从新导航到此 Page),零碎将先调用 onForeground() 回调告诉开发者,而后 Page 的生命周期状态回到 INACTIVE 状态。开发者该当在此回调中从新申请在 onBackground() 中开释的资源,最初 Page 的生命周期状态进一步回到 ACTIVE 状态,零碎将通过 onActive() 回调告诉开发者用户。

  • onStop()

    零碎将要销毁 Page 时,将会触发此回调函数,告诉用户进行系统资源的开释。销毁 Page 的可能起因包含以下几个方面:

    • 用户通过系统管理能力敞开指定 Page,例如应用工作管理器敞开 Page。
    • 用户行为触发 Page 的 terminateAbility() 办法调用,例如应用利用的退出性能。
    • 配置变更导致系统临时销毁 Page 并重建。
    • 零碎出于资源管理目标,主动触发对处于 BACKGROUND 状态 Page 的销毁。

示例代码:

咱们在 MainAbility.java 中重写以上生命周期办法,并打印 HiLog 日志:

package com.example.hanrupageabilitylifecycle;

import com.example.hanrupageabilitylifecycle.slice.MainAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.utils.PacMap;

public class MainAbility extends Ability {static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TAG_ABILITY");

    // 1. 当零碎首次创立 Page Ability 实例时,触发该回调。将进入 INACTIVE 状态
    @Override
    public void onStart(Intent intent) {super.onStart(intent);
        super.setMainRoute(MainAbilitySlice.class.getName());
        HiLog.info(LABEL, "==MainAbility--->onStart()");
    }

    // 2.Page Ability 在此之后进入 ACTIVE 状态,该状态是利用与用户交互的状态。@Override
    protected void onActive() {super.onActive();
        HiLog.info(LABEL, "==MainAbility--->onActive()");
    }

    // 3. 当 Page Ability 失去焦点时,零碎将调用此回调,尔后 Page 进入 INACTIVE 状态。@Override
    protected void onInactive() {super.onInactive();
        HiLog.info(LABEL, "==MainAbility--->onInactive()");
    }

    // 4. 如果 Page Ability 不再对用户可见,零碎将调用此回调告诉开发者用户进行相应的资源开释,尔后 Page Ability 进入 BACKGROUND 状态。@Override
    protected void onBackground() {super.onBackground();
        HiLog.info(LABEL, "==MainAbility--->onBackground()");
    }

    // 5. 处于 BACKGROUND 状态的 Page Ability 依然驻留在内存中,当从新回到前台时(比方用户从新导航到此 Page Ability),零碎将先调用 onForeground() 回调告诉开发者,而后 Page 的生命周期状态回到 INACTIVE 状态。@Override
    protected void onForeground(Intent intent) {super.onForeground(intent);
        HiLog.info(LABEL, "==MainAbility--->onForeground()");
    }

    // 6. 零碎将要销毁 Page Ability 时,将会触发此回调函数,告诉用户进行系统资源的开释。@Override
    protected void onStop() {super.onStop();
        HiLog.info(LABEL, "==MainAbility--->onStop()");
    }


}

当咱们启动我的项目,我的项目默认打印 HelloWorld:

终端打印:

06-25 16:46:06.165 18347-18347/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 16:46:06.221 18347-18347/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()

到这里,咱们能够看到,当一个我的项目启动后,依据 config.json 配置文件,首先加载 MainAbility,会先执行外面的 onStart() 和 onActive() 两个办法。

此时,而后咱们按返回键:

而后先后执行了:onInactive()–>onBackground()–>onStop()

06-25 16:50:03.231 18347-18347/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onInactive()
06-25 16:50:05.153 18347-18347/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onBackground()
06-25 16:50:05.166 18347-18347/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStop()

二、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 间导航时则由利用负责实例化。

当初咱们在 AbilitySlice 中也重写对应的生命周期办法:

package com.example.hanrupageabilitylifecycle.slice;

import com.example.hanrupageabilitylifecycle.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class MainAbilitySlice extends AbilitySlice {static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TAG_ABILITY_SLICE");
    @Override
    public void onStart(Intent intent) {super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        HiLog.info(LABEL, "==MainAbilitySlice--->onStart()");
    }

    @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()");

    }

    @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()");
    }


}

启动我的项目后:

06-25 17:05:02.011 3685-3685/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 17:05:02.031 3685-3685/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onStart()
06-25 17:05:02.041 3685-3685/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()
06-25 17:05:02.041 3685-3685/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onActive()

按下返回键:

06-25 17:08:35.311 2509-2509/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onInactive()
06-25 17:08:35.311 2509-2509/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onInactive()
06-25 17:08:36.695 2509-2509/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onBackground()
06-25 17:08:36.696 2509-2509/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onBackground()
06-25 17:08:36.701 2509-2509/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStop()
06-25 17:08:36.702 2509-2509/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onStop()

三、Page 与 AbilitySlice 生命周期关联

当 AbilitySlice 处于前台且具备焦点时,其生命周期状态随着所属 Page 的生命周期状态的变动而变动。当一个 Page 领有多个 AbilitySlice 时,例如:MyAbility 下有 MainAbilitySlice 和 SecondAbilitySlice,以后 MainAbilitySlice 处于前台并取得焦点,并行将导航到 SecondAbilitySlice,在此期间的生命周期状态变动程序为:

  1. MainAbilitySlice 从 ACTIVE 状态变为 INACTIVE 状态。
  2. SecondAbilitySlice 则从 INITIAL 状态首先变为 INACTIVE 状态,而后变为 ACTIVE 状态(假设此前 SecondAbilitySlice 未曾启动)。
  3. MainAbilitySlice 从 INACTIVE 状态变为 BACKGROUND 状态。

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

MainAbilitySlice.onInactive() –> SecondAbilitySlice.onStart() –> SecondAbilitySlice.onActive() –> MainAbilitySlicee.onBackground()

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

咱们通过代码来实现一下,打印察看日志。

咱们在 MainAbilitySlice 中增加一个按钮,点击后跳转到同一个 Ability 中的第二个 AbilitySlice:

首先批改一下 ability_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:background_element="#22aa0000"
    ohos:orientation="vertical">

    <Text
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="MainAbility"
        ohos:text_size="40vp"
        ohos:layout_alignment="horizontal_center"
        ohos:bottom_margin="20vp"
        />


    <Button
        ohos:id="$+id:btn1"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="跳转到第二个 AbilitySlice"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />

</DirectionalLayout>

扭转一下页面色彩,以及增加一个按钮。

而后咱们再新建一个 xml 布局文件:ability_second.xml

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:background_element="#2200aa00"
    ohos:orientation="vertical">

    <Text
        ohos:id="$+id:text_helloworld"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:layout_alignment="horizontal_center"
        ohos:text="SecondAbilitySlice"
        ohos:text_size="40vp"
        />

</DirectionalLayout>

而后在 slice 目录下新建一个 AbilitySlice:SecondAbilitySlice.java,并重写各个生命周期办法:

package com.example.hanrupageabilitylifecycle.slice;

import com.example.hanrupageabilitylifecycle.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class SecondAbilitySlice extends AbilitySlice {static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TAG_ABILITY_SLICE");
    @Override
    public void onStart(Intent intent) {super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_second);
        HiLog.info(LABEL, "==SecondAbilitySlice--->onStart()");
    }


    @Override
    public void onActive() {super.onActive();
        HiLog.info(LABEL, "==SecondAbilitySlice--->onActive()");
    }

    @Override
    public void onForeground(Intent intent) {super.onForeground(intent);
        HiLog.info(LABEL, "==SecondAbilitySlice--->onForeground()");

    }

    @Override
    protected void onInactive() {super.onInactive();
        HiLog.info(LABEL, "==SecondAbilitySlice--->onInactive()");
    }

    @Override
    protected void onBackground() {super.onBackground();
        HiLog.info(LABEL, "==SecondAbilitySlice--->onBackground()");
    }



    @Override
    protected void onStop() {super.onStop();
        HiLog.info(LABEL, "==SecondAbilitySlice--->onStop()");
    }
}

而后在 MainAbilitySlice 中解决按钮的点击事件:

                 // 点击按钮,跳转到 SecondAbility,察看生命周期变动
        Button btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
        btn1.setClickedListener(component -> present(new SecondAbilitySlice(),new Intent()));

而后我么启动程序,

察看日志:

06-25 17:23:07.026 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 17:23:07.046 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onStart()
06-25 17:23:07.061 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()
06-25 17:23:07.061 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onActive()

而后咱们点击按钮,跳转到第二个 AbilitySlice,察看日志:

06-25 17:23:42.768 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onInactive()
06-25 17:23:42.782 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==SecondAbilitySlice--->onStart()
06-25 17:23:42.783 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==SecondAbilitySlice--->onActive()
06-25 17:23:42.783 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onBackground()

而后咱们再按手机模拟器的返回键,这个时候,会退回到第一个页面,察看日志:

06-25 17:24:17.626 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==SecondAbilitySlice--->onInactive()
06-25 17:24:17.627 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onForeground()
06-25 17:24:17.629 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onActive()
06-25 17:24:17.629 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==SecondAbilitySlice--->onBackground()
06-25 17:24:17.629 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==SecondAbilitySlice--->onStop()

而后咱们持续按返回键,会返回到手机桌面,察看日志:

06-25 17:24:59.862 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onInactive()
06-25 17:24:59.862 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onInactive()
06-25 17:25:01.214 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onBackground()
06-25 17:25:01.214 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onBackground()
06-25 17:25:01.220 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStop()
06-25 17:25:01.221 28071-28071/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onStop()

四、Page 之间切换

上面咱们来察看一下不同的 Page Ability 之间切换的时候,生命周期,首先新建一个 Ability:OtherAbility.java:

并在外面重写生命周期的办法:

package com.example.hanrupageabilitylifecycle;

import com.example.hanrupageabilitylifecycle.slice.OtherAbilitySlice;
import com.example.hanrupageabilitylifecycle.slice.OtherAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class OtherAbility extends Ability {static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TAG_ABILITY");

    // 1. 当零碎首次创立 Page Ability 实例时,触发该回调。将进入 INACTIVE 状态
    @Override
    public void onStart(Intent intent) {super.onStart(intent);
        super.setMainRoute(OtherAbilitySlice.class.getName());
        HiLog.info(LABEL, "==OtherAbility--->onStart()");
    }

    // 2.Page Ability 在此之后进入 ACTIVE 状态,该状态是利用与用户交互的状态。@Override
    protected void onActive() {super.onActive();
        HiLog.info(LABEL, "==OtherAbility--->onActive()");
    }

    // 3. 当 Page Ability 失去焦点时,零碎将调用此回调,尔后 Page 进入 INACTIVE 状态。@Override
    protected void onInactive() {super.onInactive();
        HiLog.info(LABEL, "==OtherAbility--->onInactive()");
    }

    // 4. 如果 Page Ability 不再对用户可见,零碎将调用此回调告诉开发者用户进行相应的资源开释,尔后 Page Ability 进入 BACKGROUND 状态。@Override
    protected void onBackground() {super.onBackground();
        HiLog.info(LABEL, "==OtherAbility--->onBackground()");
    }

    // 5. 处于 BACKGROUND 状态的 Page Ability 依然驻留在内存中,当从新回到前台时(比方用户从新导航到此 Page Ability),零碎将先调用 onForeground() 回调告诉开发者,而后 Page 的生命周期状态回到 INACTIVE 状态。@Override
    protected void onForeground(Intent intent) {super.onForeground(intent);
        HiLog.info(LABEL, "==OtherAbility--->onForeground()");
    }

    // 6. 零碎将要销毁 Page Ability 时,将会触发此回调函数,告诉用户进行系统资源的开释。@Override
    protected void onStop() {super.onStop();
        HiLog.info(LABEL, "==OtherAbility--->onStop()");
    }

}

而后在生成的 OtherAbilitySlice 中重写生命周期办法:

package com.example.hanrupageabilitylifecycle.slice;

import com.example.hanrupageabilitylifecycle.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class OtherAbilitySlice extends AbilitySlice {static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TAG_ABILITY_SLICE");
    @Override
    public void onStart(Intent intent) {super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_other);
        HiLog.info(LABEL, "==OtherAbilitySlice--->onStart()");
    }


    @Override
    public void onActive() {super.onActive();
        HiLog.info(LABEL, "==OtherAbilitySlice--->onActive()");
    }

    @Override
    public void onForeground(Intent intent) {super.onForeground(intent);
        HiLog.info(LABEL, "==OtherAbilitySlice--->onForeground()");

    }

    @Override
    protected void onInactive() {super.onInactive();
        HiLog.info(LABEL, "==OtherAbilitySlice--->onInactive()");
    }

    @Override
    protected void onBackground() {super.onBackground();
        HiLog.info(LABEL, "==OtherAbilitySlice--->onBackground()");
    }



    @Override
    protected void onStop() {super.onStop();
        HiLog.info(LABEL, "==OtherAbilitySlice--->onStop()");
    }
}

批改 layout 下生成的 ability_other.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:background_element="#220000ff"
    ohos:orientation="vertical">

    <Text
        ohos:id="$+id:text_helloworld"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:layout_alignment="horizontal_center"
        ohos:text="OtherAbility"
        ohos:text_size="40vp"
        />

</DirectionalLayout>

在 ability_main.xml 中增加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:background_element="#22aa0000"
    ohos:orientation="vertical">

        ...
    <Button
        ohos:id="$+id:btn2"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="跳转到另一个 Ability"
        ohos:top_margin="20vp"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />

</DirectionalLayout>

而后在 MainAbilitySlice 中增加按钮的点击事件:

// 点击按钮,跳转到 OtherAbility,察看生命周期
        Button btn2 = (Button) findComponentById(ResourceTable.Id_btn2);
        btn2.setClickedListener(component -> {// 不同 Page 之间的导航,不能应用 present() 或者 presentForResult()
            Intent intent1 = new Intent();
            // 通过 withAbilityName() 指定要跳转到 Ability,然而须要同时应用 withBundleName()。Operation operation = new Intent.OperationBuilder()
                    .withAbilityName(OtherAbility.class)
                    .withBundleName("com.example.hanrupageabilitylifecycle")
                    .build();
            intent1.setOperation(operation);
            startAbility(intent1);

        });

而后启动程序:

察看 HiLog:

06-25 17:53:27.650 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 17:53:27.675 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onStart()
06-25 17:53:27.700 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()
06-25 17:53:27.701 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onActive()

而后点击按钮,跳转到 OtherAbility:

察看 HiLog:

06-25 17:54:02.833 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onInactive()
06-25 17:54:02.833 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onInactive()
06-25 17:54:02.928 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==OtherAbility--->onStart()
06-25 17:54:02.936 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==OtherAbilitySlice--->onStart()
06-25 17:54:02.971 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==OtherAbility--->onActive()
06-25 17:54:02.971 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==OtherAbilitySlice--->onActive()
06-25 17:54:03.805 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onBackground()
06-25 17:54:03.806 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onBackground()

而后按手机模拟器的返回键,返回到第一个界面,察看 HiLog:

06-25 17:54:52.373 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==OtherAbility--->onInactive()
06-25 17:54:52.373 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==OtherAbilitySlice--->onInactive()
06-25 17:54:52.391 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onForeground()
06-25 17:54:52.391 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onForeground()
06-25 17:54:52.394 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()
06-25 17:54:52.394 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onActive()
06-25 17:54:53.166 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==OtherAbility--->onBackground()
06-25 17:54:53.166 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==OtherAbilitySlice--->onBackground()

持续按返回键,返回到桌面:


06-25 17:54:53.168 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==OtherAbility--->onStop()
06-25 17:54:53.168 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==OtherAbilitySlice--->onStop()
06-25 17:55:45.057 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onInactive()
06-25 17:55:45.057 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onInactive()
06-25 17:55:46.363 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onBackground()
06-25 17:55:46.363 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onBackground()
06-25 17:55:46.365 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStop()
06-25 17:55:46.365 18293-18293/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY_SLICE: ==MainAbilitySlice--->onStop()

五、横竖屏切换

当手机横竖屏切换到时候,咱们看一下如何执行生命周期函数。

咱们打算在 MainAbility 设置一个成员变量 num,而后设计一个按钮,每当点击按钮,num 数值累加,并将数值显示到页面上。而后咱们横竖屏切换时,察看一下 num 数值到变动。

首先咱们批改一下 MainAbility 中的代码,咱们让 MainAbility 间接加载 xml 布局文件,并增加一个成员变量 num:

public class MainAbility extends Ability {static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TAG_ABILITY");

    private int num = 100;// 成员变量

    // 1. 当零碎首次创立 Page Ability 实例时,触发该回调。将进入 INACTIVE 状态
    @Override
    public void onStart(Intent intent) {super.onStart(intent);
//        super.setMainRoute(MainAbilitySlice.class.getName());
        super.setUIContent(ResourceTable.Layout_ability_main);


    }
  ...
}

而后我么批改一下 ability_main:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:background_element="#22aa0000"
    ohos:orientation="vertical">

    <Text
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="MainAbility"
        ohos:text_size="40vp"
        ohos:layout_alignment="horizontal_center"
        ohos:bottom_margin="20vp"
        />
    <Button
        ohos:id="$+id:btn3"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="加血加血"
        ohos:top_margin="20vp"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />

    <Text
        ohos:id="$+id:text_num"
        ohos:height="100vp"
        ohos:width="300vp"
        ohos:text_size="25fp"
        ohos:text="血量 num:100"
        ohos:layout_alignment="horizontal_center"
        ohos:background_element="#2200ff00"
        ohos:top_margin="20vp"
        ohos:text_alignment="center"
        />



    <Button
        ohos:id="$+id:btn1"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="跳转到第二个 AbilitySlice"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />
    <Button
        ohos:id="$+id:btn2"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="跳转到另一个 Ability"
        ohos:top_margin="20vp"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />



</DirectionalLayout>

咱们新增一个按钮 3,以及一个 text。

而后咱们在 MainAbility 中的 onStart() 中解决一下按钮的点击事件:

     public void onStart(Intent intent) {super.onStart(intent);
        //super.setMainRoute(MainAbilitySlice.class.getName());
        super.setUIContent(ResourceTable.Layout_ability_main);

        initComponent();

        btn.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                num++;
                textNum.setText("数值 num:"+num);
            }
        });

        HiLog.info(LABEL, "==MainAbility--->onStart()");
    }
        private void initComponent(){btn = (Button) findComponentById(ResourceTable.Id_btn3);
        textNum = (Text) findComponentById(ResourceTable.Id_text_num);
    }

而后咱们运行程序:

咱们运行后,点击按钮,将 num 的值累加到 103,

而后切换横竖屏,发现 num 的值又变回 100 了。

察看 HiLog 日志:

06-25 19:57:02.990 22192-22192/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 19:57:03.008 22192-22192/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()
06-25 19:58:15.003 22192-22192/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onInactive()
06-25 19:58:15.146 22192-22192/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onBackground()
06-25 19:58:15.148 22192-22192/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStop()
06-25 19:58:15.298 22192-22192/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 19:58:15.382 22192-22192/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()

咱们发现,顺次执行了 onInactive()–>onBackground()–>onStop(),而后会从新执行 onStart(),onActive() 办法,所以切换到横屏后,num 的数值又变回了 100。

那如果想保留 num 的数值,还要再借助于两个生命周期函数:onSaveAbilityState() 和 onRestoreAbilityState():

    @Override
    public void onSaveAbilityState(PacMap outState) {super.onSaveAbilityState(outState);
        HiLog.info(LABEL, "==MainAbility--->onSaveAbilityState()");

        outState.putIntValue("num", num);
    }

    @Override
    public void onRestoreAbilityState(PacMap inState) {super.onRestoreAbilityState(inState);
        HiLog.info(LABEL, "==MainAbility--->onRestoreAbilityState()");
        num = inState.getIntValue("num");
        textNum.setText("血量 num:"+num);
    }

咱们从新运行一下:

咱们再来察看一下生命周期函数:

06-25 20:03:33.150 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 20:03:33.171 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()
06-25 20:03:57.537 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onInactive()
06-25 20:03:57.584 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onBackground()
06-25 20:03:57.585 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onSaveAbilityState()
06-25 20:03:57.586 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStop()
06-25 20:03:57.761 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onStart()
06-25 20:03:57.764 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onRestoreAbilityState()
06-25 20:03:57.770 9044-9044/com.example.hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()

最终切换到横屏之后,num 也是 103,完满。😄

正文完
 0