Activity的生命周期
本文描述Android中Activity生命周期方法,通过重写生命周期的方法打印对应的Log,分析在一些常见的情况下,分别调用了什么方法,从而总结理解Activity的生命周期;
以下是Activity的七种生命周期方法,中文说明如下:
生命周期方法 | 作用 | 说明 | 方法后Activity处于什么状态? |
onCreate | 表示 Activity 正在被创建 | activity 被创建时调用,一般在这个方法中进行活动的初始化工作,如设置布局工作、加载数据、绑定控件等。 | 不可见不可交互 |
onRestart | 表示 Activity 正在重新启动 | 这个回调代表了 Activity 由完全不可见重新变为可见的过程,当 Activity 经历了 onStop() 回调变为完全不可见后,如果用户返回原 Activity,便会触发该回调,并且紧接着会触发 onStart() 来使活动重新可见。 | 触发onStart() |
onStart | 表示 Activity 正在被启动 | 经历该回调后,Activity 由不可见变为可见,但此时处于后台可见,还不能和用户进行交互。 | 可见不可交互 |
onResume | 表示 Activity 已经可见 | 已经可见的 Activity 从后台来到前台,可以和用户进行交互。 | 可见可交互 |
onPause | 表示 Activity 正在停止 | 当用户启动了新的 Activity ,原来的 Activity 不再处于前台,也无法与用户进行交互,并且紧接着就会调用 onStop() 方法,但如果用户这时立刻按返回键回到原 Activity ,就会调用 onResume() 方法让活动重新回到前台。而且在官方文档中给出了说明,不允许在 onPause() 方法中执行耗时操作,因为这会影响到新 Activity 的启动。 | 可见不可交互 |
onStop | 表示 Activity 即将停止 | 这个回调代表了 Activity 由可见变为完全不可见,在这里可以进行一些稍微重量级的操作。需要注意的是,处于 onPause() 和 onStop() 回调后的 Activity 优先级很低,当有优先级更高的应用需要内存时,该应用就会被杀死,那么当再次返回原 Activity 的时候,会重新调用 Activity 的onCreate()方法。 | 不可见不可交互 |
onDestroy | 表示 Activity 即将被销毁 | 来到了这个回调,说明 Activity 即将被销毁,应该将资源的回收和释放工作在该方法中执行。 | 已销毁 |
附上测试DEMO:
package com.example.lifecycle;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class LifeCycleActivity extends AppCompatActivity {
private static final String TAG = "LifeCycleActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "----onCreate----");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "----onRestart----");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "----onStart----");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "----onResume----");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "----onPause----");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "----onStop----");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "----onDestroy----");
}
}
1、打开Apk后,点击返回键返回到桌面后,再重新打开APK;
1970-01-01 08:01:39.643 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onCreate----
1970-01-01 08:01:39.646 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onStart----
1970-01-01 08:01:39.648 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onResume----
1970-01-01 08:01:48.338 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onPause----
1970-01-01 08:01:48.610 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onStop----
1970-01-01 08:01:48.613 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onDestroy----
1970-01-01 08:02:57.806 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onCreate----
1970-01-01 08:02:57.807 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onStart----
1970-01-01 08:02:57.809 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onResume----
结论:可以看到点击返回键会把Activity销毁掉,重新打开会重新走onCreate-onStart-onResume声明周期方法;
2、打开Apk后,点击home键返回到桌面后,再重新打开APK;
1970-01-01 08:05:07.656 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onCreate----
1970-01-01 08:05:07.656 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onStart----
1970-01-01 08:05:07.658 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onResume----
1970-01-01 08:05:09.570 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onPause----
1970-01-01 08:05:09.609 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onStop----
1970-01-01 08:05:18.114 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onRestart----
1970-01-01 08:05:18.116 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onStart----
1970-01-01 08:05:18.117 2451-2451/com.example.lifecycle D/LifeCycleActivity: ----onResume----
结论:可以看到点击home键并没有把Activity销毁掉,既然没有销毁就不需要重新创建;重新打开会重新走onRestart-onStart-onResume声明周期方法;
3、通过EditText弹出软键盘以及从顶部划出导航栏;
无log输出,结论:通过EditText弹出软键盘以及从顶部划出导航栏没有调用任何生命周期方法,此时Activity一直处于可交互可见状态;
4、在Activity界面旋转屏幕:
2021-05-08 00:49:14.386 15721-15721/? D/LifeCycleActivity: ----onCreate----
2021-05-08 00:49:14.388 15721-15721/? D/LifeCycleActivity: ----onStart----
2021-05-08 00:49:14.389 15721-15721/? D/LifeCycleActivity: ----onResume----
2021-05-08 00:49:18.662 15721-15721/com.example.lifecycle D/LifeCycleActivity: ----onPause----
2021-05-08 00:49:18.663 15721-15721/com.example.lifecycle D/LifeCycleActivity: ----onStop----
2021-05-08 00:49:18.664 15721-15721/com.example.lifecycle D/LifeCycleActivity: ----onDestroy----
2021-05-08 00:49:18.729 15721-15721/com.example.lifecycle D/LifeCycleActivity: ----onCreate----
2021-05-08 00:49:18.732 15721-15721/com.example.lifecycle D/LifeCycleActivity: ----onStart----
2021-05-08 00:49:18.733 15721-15721/com.example.lifecycle D/LifeCycleActivity: ----onResume----
结论:当在Activity界面旋转屏幕会销毁并重新创建Activity,即完整的走了一遍生命周期;
是否有方法不让Activity重新走生命周期呢?在注册Activity中添加android:configChanges="orientation|keyboardHidden|screenSize"即可;
<activity android:name=".LifeCycleActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
5、熄屏之后再亮屏
2021-05-08 00:55:44.818 16418-16418/com.example.lifecycle D/LifeCycleActivity: ----onPause----
2021-05-08 00:55:44.855 16418-16418/com.example.lifecycle D/LifeCycleActivity: ----onStop----
2021-05-08 00:55:46.856 16418-16418/com.example.lifecycle D/LifeCycleActivity: ----onRestart----
2021-05-08 00:55:46.857 16418-16418/com.example.lifecycle D/LifeCycleActivity: ----onStart----
2021-05-08 00:55:46.859 16418-16418/com.example.lifecycle D/LifeCycleActivity: ----onResume----
结论:和点击home键返回是一样的,并没有被销毁;
6、打开一个透明的Activity再返回
配置方法:
<activity android:name=".secondActivity"
android:theme="@android:style/Theme.Translucent">
</activity>
1970-01-01 08:14:32.194 2686-2686/com.example.lifecycle D/LifeCycleActivity: ----onPause----
1970-01-01 08:14:34.979 2686-2686/com.example.lifecycle D/LifeCycleActivity: ----onResume----
结论:打开一个透明的Activity,原始的Acivity只执行了onPause生命周期方法,此时不可交互,但是仍然可见;
Activity的启动模式
任务栈
任务栈Task,是一种用来放置Activity实例的容器,他是以栈的形式进行盛放,也就是所谓的先进后出,主要有2个基本操作:压栈和出栈,其所存放的Activity是不支持重新排序的,只能根据压栈和出栈操作更改Activity的顺序。启动一个Application的时候,系统会为它默认创建一个对应的Task,用来放置根Activity。默认启动Activity会放在同一个Task中,新启动的Activity会被压入启动它的那个Activity的栈中,并且显示它。当用户按下回退键时,这个Activity就会被弹出栈,按下Home键回到桌面,再启动另一个应用,这时候之前那个Task就被移到后台,成为后台任务栈,而刚启动的那个Task就被调到前台,成为前台任务栈,手机页面显示的就是前台任务栈中的栈顶元素。
Activity的启动模式
- 标准模式(standard)
- 栈顶复用模式(singleTop)
- 栈内复用模式(singleTask)
- 单例模式(singleInstance)
标准模式(standard)
在清单文件中不进行任何的配置,默认即为standard,在这种模式下,只要启动了一次Activity,就会把该Activity创建并放到栈顶,启动N次在栈中会有N个实例元素,简单来说需要按N次返回键进行销毁;
使用环境:大多数都是使用这个模式;
栈顶复用模式(singleTop)
在这种模式下,如果启动的Activity,已经位于栈顶,那么Activity将不会重复创建,这个Activity的onCreate、onStart都不会被系统调用,只会重新调用 onNewIntent方法;但是如果不处于栈顶,仍然会重新创建并置于栈顶;
使用环境:比如浏览器的书签,应用的通知推送;
栈内复用模式(singleTask)
在这种模式下,如果启动的Activity,已经位于栈中任意位置,他会把位于该Activity之上的实例都销毁掉(出栈),使得该Activity位于栈顶;如果启动前已经位于栈顶,只会重新调用 onNewIntent方法;
使用环境:当我们这个任务资源相对比较大的时候
单例模式(singleInstance)
在这种模式下,启动之后会重新创建一个任务栈task,独立与其他任务栈,在这个任务栈中只有单一一种实例,该任务栈与其他任务栈会有先后顺序,启动之后会位于前者;销毁之后会回到另一个任务栈;
使用环境:在整个系统中只有唯一一个实例,比如说我们做的Launcher、有道词典的取词(每个界面都可以取词)
配置方法
android:launchMode="standard"