2, Page Ability lifecycle

Author: Han Ru

Company: Program Ka (Beijing) Technology Co., LTD

Hong Meng Bus columnist

Actions such as system administration or user actions can cause a Page instance to transition between different states in its life cycle. The Ability class provides a callback mechanism that allows the Page to sense changes in the environment and react properly to state changes (such as releasing resources), which can help improve application performance and robustness.

Page lifecycle callback

Page Ability is responsible for Page interaction, so a Page has several states: visible, interactive, invisible, destroyed, and so on. For each state, there is a life cycle function corresponding to it. The different state transitions of the Page life cycle and their corresponding callbacks are shown in the figure below. (Photo from official website)

  • onStart()

    This callback is triggered when the system first creates a Page instance. For a Page instance, the callback is triggered only once during its life cycle, and the Page will enter INACTIVE state after the logic. The developer must override this method and configure AbilitySlice to be displayed by default here.

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

    Page comes to the foreground after it enters INACTIVE state, and the system calls this callback. Page then enters the ACTIVE state, which indicates the interaction between the application and the user. The Page will remain in this state unless some sort of event occurs that causes the Page to lose focus, such as the user clicking the back key or navigating to another Page. When such an event occurs, the Page is triggered to return to INACTIVE and the onInactive() callback is called. After that, the Page may return to the ACTIVE state, and the onActive() callback will be invoked again. Therefore, developers usually need to implement onActive() and onInactive() in pairs, and in onActive() take the resources released in onInactive().

  • onInactive()

    This callback is invoked when the Page loses focus, after which the Page enters INACTIVE state. This callback allows developers to implement the appropriate behavior that a Page should behave when it loses focus.

  • onBackground()

    If the Page is no longer visible to the user, the system calls this callback to notify the developer user of the appropriate resource release, after which the Page enters the BACKGROUND state. This callback should either free resources that are useless when the Page is not visible, or perform time-consuming state saving operations in this callback.

  • onForeground()

    BACKGROUND pages remain in memory. When returned to foreground (for example, when the user navigates to the Page again), the onForeground() callback is called to notify the developer, and the Page’s life cycle state returns to INACTIVE. The developer should reapply for the resources released in onBackground() in this callback, and eventually the Page’s lifecycle state will return further to the ACTIVE state, and the developer user will be notified via the onActive() callback.

  • onStop()

    This callback is triggered when the system is about to destroy the Page, notifying the user of the release of system resources. Possible reasons for Page destruction include:

    • The user can close a Page using the system management capability, for example, using the task manager to close a Page.
    • The Page’s terminateAbility() method is triggered by user action, such as using the application’s exit function.
    • The configuration change caused the system to temporarily destroy the Page and rebuild.
    • For resource management purposes, the system automatically triggers the destruction of BACKGROUND pages.

Sample code:

We override the above lifecycle methods in mainability.java and print the HiLog log:

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. This callback is triggered when the system first creates an instance of Page Ability. Will enter INACTIVE state
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(MainAbilitySlice.class.getName());
        HiLog.info(LABEL, "==MainAbility--->onStart()");
    }

    // 2.Page Ability then enters the ACTIVE state, which is the state in which the application interacts with the user.
    @Override
    protected void onActive(a) {
        super.onActive();
        HiLog.info(LABEL, "==MainAbility--->onActive()");
    }

    // 3. This callback is invoked when Page Ability loses focus, after which Page enters INACTIVE state.
    @Override
    protected void onInactive(a) {
        super.onInactive();
        HiLog.info(LABEL, "==MainAbility--->onInactive()");
    }

    // 4. If Page Ability is no longer visible to the user, this callback will be called to inform the developer of the appropriate resource release, after which Page Ability enters the BACKGROUND state.
    @Override
    protected void onBackground(a) {
        super.onBackground();
        HiLog.info(LABEL, "==MainAbility--->onBackground()");
    }

    // 5. The BACKGROUND Page Ability remains in memory, and when returned to foreground (e.g. user navigates to this Page Ability), the onForeground() callback will be called to notify the developer, The Page life cycle state then returns to INACTIVE.
    @Override
    protected void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(LABEL, "==MainAbility--->onForeground()");
    }

    // 6. This callback is triggered when the system is about to destroy Page Ability, notifying the user to release system resources.
    @Override
    protected void onStop(a) {
        super.onStop();
        HiLog.info(LABEL, "==MainAbility--->onStop()"); }}Copy the code

When we start the project, the project defaults to printing HelloWorld:

Terminal printing:

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()

Copy the code

Here, we can see that when a project is started, MainAbility is first loaded according to the config.json configuration file, and the onStart() and onActive() methods are executed first.

At this point, then we press the Back key:

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()
Copy the code

AbilitySlice Life cycle

AbilitySlice is a component of a Page and its life cycle depends on the Page life cycle to which it belongs. AbilitySlice has the same life cycle state and callback of the same name as Page, and its AbilitySlice has the same life cycle change when the Page life cycle changes. In addition, AbilitySlice has page-independent lifecycle changes that occur when a AbilitySlice navigates between pages in the same Page without changing the Page lifecycle status.

The AbilitySlice lifecycle callback is similar to the corresponding Page callback and will not be described here. Since AbilitySlice hosts a specific page, the developer must override AbilitySlice’s onStart() callback and set up the page in this method via the setUIContent() method, as shown below:

    @Override    
    protected void onStart(Intent intent) {        
    	super.onStart(intent);
      setUIContent(ResourceTable.Layout_main_layout);    
    }
Copy the code

AbilitySlice instances are created and managed by applications. The system creates AbilitySlice instances only in specific situations. For example, when a AbilitySlice is launched by navigation, the system is responsible for instantiation; However, the application is responsible for instantiating navigation between AbilitySlice in the same Page.

Now we can rewrite the corresponding lifecycle methods in AbilitySlice as well:

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(a) {
        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(a) {
        super.onInactive();
        HiLog.info(LABEL, "==MainAbilitySlice--->onInactive()");
    }

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



    @Override
    protected void onStop(a) {
        super.onStop();
        HiLog.info(LABEL, "==MainAbilitySlice--->onStop()"); }}Copy the code

After starting the project:

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()
Copy the code

Press the Return key:

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()
Copy the code

Page is associated with the AbilitySlice life cycle

When AbilitySlice is in the foreground and in focus, its life cycle state changes with the life cycle state of the Page to which it belongs. When a Page has more than one AbilitySlice, for example: There are MainAbilitySlice and SecondAbilitySlice under MyAbility. Currently MainAbilitySlice is in the foreground and gets focus, and is about to navigate to SecondAbilitySlice. During this period, the life cycle status changes in the following order:

  1. MainAbilitySlice Changes from the ACTIVE state to INACTIVE state.
  2. SecondAbilitySlice changes from INITIAL to INACTIVE and then ACTIVE (assuming SecondAbilitySlice has not been started before).
  3. MainAbilitySlice Changes from INACTIVE to BACKGROUND.

The lifecycle method callback order for the two slices is:

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

MyAbility remains ACTIVE throughout the process. However, when a Page is destroyed by the system, all of its instantiated AbilitySlice will be destroyed in linkage, not just AbilitySlice in the foreground.

Let’s do this in code, print an observation log.

We add a button to MainAbilitySlice that jumps to the second AbilitySlice in the same Ability:

First modify 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="Jump to the second AbilitySlice"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />

</DirectionalLayout>
Copy the code

Change the page color and add a button.

Then we create a new XML layout file: 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>
Copy the code

Then create a new AbilitySlice: SecondAbilitySlice. Java in the Slice directory and rewrite the various lifecycle methods:

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(a) {
        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(a) {
        super.onInactive();
        HiLog.info(LABEL, "==SecondAbilitySlice--->onInactive()");
    }

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



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

Then handle button click events in MainAbilitySlice:

 				// Click the button to jump to SecondAbility and observe life cycle changes
        Button btn1 = (Button) findComponentById(ResourceTable.Id_btn1);
        btn1.setClickedListener(component -> present(new SecondAbilitySlice(),new Intent()));

Copy the code

And then we start the program,

Observation log:

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()
Copy the code

Then we click the button to jump to the second AbilitySlice and observe the log:

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()
Copy the code

Then we press the back button of the mobile phone simulator. At this time, we will return to the first page and observe the log:

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()
Copy the code

Then we continue to press the back button to return to the mobile phone desktop and observe the log:

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()
Copy the code

4. Switch between pages

Create a new Ability: otherability.java when switching between Page Ability: otherability.java:

And override the lifecycle methods in it:

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. This callback is triggered when the system first creates an instance of Page Ability. Will enter INACTIVE state
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(OtherAbilitySlice.class.getName());
        HiLog.info(LABEL, "==OtherAbility--->onStart()");
    }

    // 2.Page Ability then enters the ACTIVE state, which is the state in which the application interacts with the user.
    @Override
    protected void onActive(a) {
        super.onActive();
        HiLog.info(LABEL, "==OtherAbility--->onActive()");
    }

    // 3. This callback is invoked when Page Ability loses focus, after which Page enters INACTIVE state.
    @Override
    protected void onInactive(a) {
        super.onInactive();
        HiLog.info(LABEL, "==OtherAbility--->onInactive()");
    }

    // 4. If Page Ability is no longer visible to the user, this callback will be called to inform the developer of the appropriate resource release, after which Page Ability enters the BACKGROUND state.
    @Override
    protected void onBackground(a) {
        super.onBackground();
        HiLog.info(LABEL, "==OtherAbility--->onBackground()");
    }

    // 5. The BACKGROUND Page Ability remains in memory, and when returned to foreground (e.g. user navigates to this Page Ability), the onForeground() callback will be called to notify the developer, The Page life cycle state then returns to INACTIVE.
    @Override
    protected void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(LABEL, "==OtherAbility--->onForeground()");
    }

    // 6. This callback is triggered when the system is about to destroy Page Ability, notifying the user to release system resources.
    @Override
    protected void onStop(a) {
        super.onStop();
        HiLog.info(LABEL, "==OtherAbility--->onStop()"); }}Copy the code

Then override the lifecycle method in the generated 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(a) {
        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(a) {
        super.onInactive();
        HiLog.info(LABEL, "==OtherAbilitySlice--->onInactive()");
    }

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



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

Modify the ability_other. XML file generated under Layout:

<? 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>
Copy the code

Add a button to 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="Jump to another Ability"
        ohos:top_margin="20vp"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />

</DirectionalLayout>
Copy the code

Then add the button click event in MainAbilitySlice:

// Click the button to jump to OtherAbility and observe the lifecycle
        Button btn2 = (Button) findComponentById(ResourceTable.Id_btn2);
        btn2.setClickedListener(component -> {
            Present () or presentForResult() cannot be used for navigation between different pages
            Intent intent1 = new Intent();
            // Specify with withAbilityName() to jump to Ability, but with withBundleName().
            Operation operation = new Intent.OperationBuilder()
                    .withAbilityName(OtherAbility.class)
                    .withBundleName("com.example.hanrupageabilitylifecycle")
                    .build();
            intent1.setOperation(operation);
            startAbility(intent1);

        });

Copy the code

Then start the program:

Watch 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()
Copy the code

Then click the button to jump to OtherAbility:

Watch 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()
Copy the code

Then press the back button of the phone emulator to return to the first screen and observe 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()
Copy the code

Continue pressing the Back key to return to the desktop:


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()
Copy the code

Five, horizontal and vertical screen switching

Let’s take a look at how to implement the lifecycle function when the phone switches from horizontal to vertical.

We are going to set a member variable num in MainAbility, and then design a button that will add num values and display them on the page every time the button is clicked. Then we watch the num value change as we switch between vertical and horizontal screens.

First we modify the code in MainAbility. We let MainAbility load the XML layout file directly and add a member variable num:

public class MainAbility extends Ability {

    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201."TAG_ABILITY");

    private int num = 100;// Member variables

    // 1. This callback is triggered when the system first creates an instance of Page Ability. Will enter INACTIVE state
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
// super.setMainRoute(MainAbilitySlice.class.getName());
        super.setUIContent(ResourceTable.Layout_ability_main); }... }Copy the code

Then we can modify 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="Blood and blood."
        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="Jump to the second 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="Jump to another Ability"
        ohos:top_margin="20vp"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        />



</DirectionalLayout>
Copy the code

We’ll add a button 3 and a text.

Then we handle the button click event in onStart() in MainAbility:

 	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(a){
        btn = (Button) findComponentById(ResourceTable.Id_btn3);
        textNum = (Text) findComponentById(ResourceTable.Id_text_num);
    }

Copy the code

Then we run the program:

After we run it, we hit the button and add num to 103,

Then switch the vertical screen and find that num is changed back to 100.

Observe the HiLog log:

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()
Copy the code

After executing onInactive()–>onBackground()–>onStop(), the onStart() and onActive() methods will be executed again, so when we switch to landscape, num will change back to 100.

To preserve the value of num, use two lifecycle functions: onSaveAbilityState() and 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("Blood volume num:"+num);
    }
Copy the code

Let’s run it again:

Let’s look at the life cycle function again:

06-25 20:03:33. 150, 9044-9044 / com. Example. 00201 / TAG_ABILITY hanrupageabilitylifecycle I: = = MainAbility - > onStart () '06-25 20:03:33. 171, 9044-9044 / com. Example. 00201 / TAG_ABILITY hanrupageabilitylifecycle I: = = MainAbility - > onActive () '06-25 20:03:57. 537, 9044-9044 / com. Example. 00201 / TAG_ABILITY hanrupageabilitylifecycle I: = = MainAbility - > onInactive () '06-25 20:03:57. 584, 9044-9044 / com. Example. 00201 / TAG_ABILITY hanrupageabilitylifecycle I: = = MainAbility - > onBackground () '06-25 20:03:57. 585, 9044-9044 / com. Example. 00201 / TAG_ABILITY hanrupageabilitylifecycle I: = = 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. 00201 / TAG_ABILITY hanrupageabilitylifecycle I: = = MainAbility - > onStart () '06-25 20:03:57. 764, 9044-9044 / com. Example. 00201 / TAG_ABILITY hanrupageabilitylifecycle I: = = MainAbility - > onRestoreAbilityState () 06-25 20:03:57. 770, 9044-9044 / com. Example. Hanrupageabilitylifecycle I 00201/TAG_ABILITY: ==MainAbility--->onActive()Copy the code

When I finally switch to landscape, NUM is also 103, perfect. 😄