The life cycle of Java backend Android activity

Posted by 00king00 on Fri, 18 Feb 2022 15:56:17 +0100

Activity lifecycle

Activities in Android can be superimposed, which also means that each activity should have a corresponding life cycle. The onCreate method is used every time, which is also an important method in the life cycle function

The person in charge of each activity is called the activity stack. Obviously, one activity can be superimposed on another activity, which requires the first in and last out data structure of the stack. Whenever a new activity is started, it will be put on the return stack, and the system will always display the activity at the top of the stack to the user

1.1 activity status

  • Running state: when an activity is at the top of the return stack, the activity is in running state
  • Pause state: when an activity is not at the top of the stack, it is still visible. The reason for this state is that not every activity needs to fill a screen, such as some dialog activities
  • Stop state: when an activity is not at the top of the stack and is completely invisible, it is in the stop state. The system will still save the corresponding state and variables for this activity, but when memory is needed elsewhere in the system, the activity in the stop state will be recycled by the system
  • Destroy state: when an activity is removed from the return stack, it is in the destroy state

1.2 activity survival

Seven callback methods are defined in the Activity class, covering every link of the Activity life cycle

  • onCreate(): you have seen this method many times. We have rewritten this method in each activity. It will be called when the activity is created for the first time. You should initialize activities in this method, such as loading layout, binding events, etc.

  • onStart(): this method is called when the activity changes from invisible to visible.

  • onResume(): this method is called when the activity is ready to interact with the user. At this time, the activity must be at the top of the return stack and in running state.

  • onPause(): this method is called when the system is ready to start or resume another activity. We usually release some CPU consuming resources and save some key data in this method, but the execution speed of this method must be fast, otherwise it will affect the use of new stack top activities.

  • onStop(): this method is called when the activity is completely invisible. The main difference between it and onPause() method is that if the new activity started is a dialog activity, onPause() method will be executed, while onStop() method will not be executed.

  • onDestroy(): this method is called before the activity is destroyed, and then the state of the activity will be destroyed.

  • onRestart(): this method is called before the activity changes from stop state to running state, that is, the activity is restarted. Among the above seven methods, except onRestart() method, the others are relative to each other, so the activities can be divided into three survival periods.

Complete survival

What an activity goes through between the onCreate() method and the onDestroy() method is the full lifetime. In general, an activity will complete various initialization operations in the onCreate() method, and complete the operation within the release in the onDestroy() method.

Visible survival

What an activity goes through between the onStart() method and the onStop() method is the visible lifetime. During the visible lifetime, activities are always visible to users, even if they may not be able to interact with users. Through these two methods, we can reasonably manage the resources visible to users. For example, the resources are loaded in the onStart() method and released in the onStop() method, so as to ensure that the activities in the stopped state will not occupy too much memory.

Foreground lifetime

What an activity goes through between the onResume() method and the onPause() method is the foreground lifetime. During the lifetime of the foreground, activities are always in the running state. At this time, activities can interact with users. We usually see and contact the most activities in this state.

1.4 experience life cycle

Environment construction: three activities: MainActivity, NormalActivity and DialogActivity, which means main Activity, normal Activity (activities covering the whole screen) and dialog form Activity (activities that do not need to temporarily fill the whole screen). Three layout files

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("Create method", "onCreate");

        Button normalButton = (Button) this.findViewById(R.id.button_1);
        normalButton.setOnClickListener((View v) -> {
            Intent intent = new Intent(this, NormalActivity.class);
            this.startActivity(intent);
        });
        Button dialogButton = (Button) this.findViewById(R.id.button_2);
        dialogButton.setOnClickListener((View v) -> {
            Intent intent = new Intent(this, DialogActivity.class);
            this.startActivity(intent);
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Start method", "OnStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Prepare for interaction", "OnResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Activity starts another activity", "OnPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Activity pause", "OnStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Activity destruction", "onDestroy");
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    
    <Button
        android:id="@+id/button_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Normal Activity">
    </Button>

    <Button
        android:id="@+id/button_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Dialog Activity">
    </Button>

</LinearLayout>

NormalActivity.java

public class NormalActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.normal_layout);
    }
}

normal_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NormalActivity">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is normal activity"></TextView>

</LinearLayout>

DialogActivity.java

public class DialogActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_layout);
        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setTitle("This is Dialog");
        dialog.setMessage("Something id Dialog");
    }
}

dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DialogActivity">

</LinearLayout>

Cross reference life cycle diagram

When you run AS, you first arrive at MainActivity. Naturally, you run its onCreate(), OnStart(), OnResume() methods. You can see the logcat log

When you click the Normal Activity button, you will switch to another activity, but this activity is an activity that needs to temporarily fill the whole screen, so it is an activity within the visible lifetime

When you click the back button, you return to MainActivity

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-5yA0W3YC-1619922998337)(Java back-end learning Android(3)] - the life cycle of the activity and the startup mode of the activity assets/image-20210502102248065.png)

In other words, for MainActivity, start NormalActivity and finally return to MainActivity. The methods experienced are:

OnCreate -> OnStart -> OnResume -> OnPause -> OnStop -> OnRestart -> OnStart -> OnResume

Then experiment with MainActivity, start DialogActivity, and finally return to MainActivity activity

Press the back key to return to the operation method pointed by the arrow in the flowchart

In other words, MainActivity starts DialogActivity and finally returns to MainActivity activity. The methods experienced are

OnCreate -> OnStart -> OnResume -> OnPause -> OnResume

Finally, exit the whole program and execute OnDestroy method

1.5 what if the activity is recycled

Activity a starts activity B. if the memory space is insufficient at this time, the system reclaims activity A. when we click back (in activity B at this time), the system reruns onCreate method to execute a complete life cycle. However, if there are some important temporary data in a, but they are forcibly recovered by the system, these data will naturally be lost, which will greatly affect the system operation or user experience

You can use the onSaveInstanceState method, and you can see that a Bundle variable is bound inside. Yes, it is

protected void onSaveInstanceState(@NonNull Bundle outState)

Some important temporary data is saved in the Bundle and then taken out in the onCreate method, because there is also a Bundle variable in the onCreate method, which can be used to transfer data.

Naturally, it is also lost, which will greatly affect the system operation or user experience

You can use the onSaveInstanceState method, and you can see that a Bundle variable is bound inside. Yes, it is

protected void onSaveInstanceState(@NonNull Bundle outState)

Some important temporary data is saved in the Bundle and then taken out in the onCreate method, because there is also a Bundle variable in the onCreate method, which can be used to transfer data.

So far, I have learned to use Intent to transfer data on different activities and Bundle to transfer data between different life cycles. Of course, it can also be used in combination

Topics: Java Android