转载于 https://blog.csdn.net/Natsume_for_ever/article/details/107840402
1. Activity简介
Activity 类是 Android 应用的关键组件,而 Activity 的启动和组合方式则是该平台应用模型的基本组成部分。在编程范式中,应用是通过 main() 方法启动的,而 Android 系统与此不同,它会调用与其生命周期特定阶段相对应的特定回调方法来启动 Activity 实例中的代码。
2. Activity概念
移动应用体验与桌面体验的不同之处在于,用户与应用的互动并不总是在同一位置开始,而是经常以不确定的方式开始。例如,如果您从主屏幕打开电子邮件应用,可能会看到电子邮件列表,如果您通过社交媒体应用启动电子邮件应用,则可能会直接进入电子邮件应用的邮件撰写界面。
Activity 类的目的就是促进这种范式的实现。当一个应用调用另一个应用时,调用方应用会调用另一个应用中的 Activity,而不是整个应用。通过这种方式,Activity 充当了应用与用户互动的入口点。您可以将 Activity 实现为 Activity 类的子类。
Activity 提供窗口供应用在其中绘制界面。此窗口通常会填满屏幕,但也可能比屏幕小,并浮动在其他窗口上面。通常,一个 Activity 实现应用中的一个屏幕。例如,应用中的一个 Activity 实现“偏好设置”屏幕,而另一个 Activity 实现“选择照片”屏幕。
大多数应用包含多个屏幕,这意味着它们包含多个 Activity。通常,应用中的一个 Activity 会被指定为主 Activity,这是用户启动应用时出现的第一个屏幕。然后,每个 Activity 可以启动另一个 Activity,以执行不同的操作。例如,一个简单的电子邮件应用中的主 Activity 可能会提供显示电子邮件收件箱的屏幕。主 Activity 可能会从该屏幕启动其他 Activity,以提供执行写邮件和打开邮件这类任务的屏幕。
虽然应用中的各个 Activity 协同工作形成统一的用户体验,但每个 Activity 与其他 Activity 之间只存在松散的关联,应用内不同 Activity 之间的依赖关系通常很小。事实上,Activity 经常会启动属于其他应用的 Activity。例如,浏览器应用可能会启动社交媒体应用的“分享”Activity。
要在应用中使用 Activity,您必须在应用的清单中注册关于 Activity 的信息,并且必须适当地管理 Activity 的生命周期。
3. Activity的生命周期
从官方给出的文档中,我们可以看到,activity是我们APP中最基础的组件之一,而activity的生命周期又是我们控制activity的基础,所以要想做好安卓开发,下面这张生命周期图,我们必须牢记
为了在 Activity 生命周期的各个阶段之间导航转换,Activity 类提供六个核心回调:onCreate()、onStart()、onResume()、onPause()、onStop() 和 onDestroy(),当 Activity 进入新状态时,系统会调用其中每个回调。
onCreate()
您必须实现此回调,它会在系统创建您的 Activity 时触发。您的实现应该初始化 Activity 的基本组件:例如,您的应用应该在此处创建视图并将数据绑定到列表。最重要的是,您必须在此处调用 setContentView() 来定义 Activity 界面的布局。
onCreate() 完成后,下一个回调将是 onStart()。
onStart()
onCreate() 退出后,Activity 将进入“已启动”状态,并对用户可见。此回调包含 Activity 进入前台与用户进行互动之前的最后准备工作。
onResume()
系统会在 Activity 开始与用户互动之前调用此回调。此时,该 Activity 位于 Activity 堆栈的顶部,并会捕获所有用户输入。应用的大部分核心功能都是在 onResume() 方法中实现的。
onResume() 回调后面总是跟着 onPause() 回调。
onPause()
当 Activity 失去焦点并进入“已暂停”状态时,系统就会调用 onPause()。例如,当用户点按“返回”或“最近使用的应用”按钮时,就会出现此状态。当系统为您的 Activity 调用 onPause() 时,从技术上来说,这意味着您的 Activity 仍然部分可见,但大多数情况下,这表明用户正在离开该 Activity,该 Activity 很快将进入“已停止”或“已恢复”状态。
如果用户希望界面继续更新,则处于“已暂停”状态的 Activity 也可以继续更新界面。例如,显示导航地图屏幕或播放媒体播放器的 Activity 就属于此类 Activity。即使此类 Activity 失去了焦点,用户仍希望其界面继续更新。
您不应使用 onPause() 来保存应用或用户数据、进行网络呼叫或执行数据库事务。onPause() 执行完毕后,下一个回调为 onStop()或 onResume(),具体取决于 Activity 进入“已暂停”状态后发生的情况。
onStop()
当 Activity 对用户不再可见时,系统会调用 onStop()。出现这种情况的原因可能是 Activity 被销毁,新的 Activity 启动,或者现有的 Activity 正在进入“已恢复”状态并覆盖了已停止的 Activity。在所有这些情况下,停止的 Activity 都将完全不再可见。
系统调用的下一个回调将是 onRestart()(如果 Activity 重新与用户互动)或者 onDestroy()(如果 Activity 彻底终止)。
onRestart()
当处于“已停止”状态的 Activity 即将重启时,系统就会调用此回调。onRestart() 会从 Activity 停止时的状态恢复 Activity。
此回调后面总是跟着 onStart()。
onDestroy()
系统会在销毁 Activity 之前调用此回调。
此回调是 Activity 接收的最后一个回调。通常,实现 onDestroy() 是为了确保在销毁 Activity 或包含该 Activity 的进程时释放该 Activity 的所有资源。
接下来用代码来给大家演示一下,生命周期的流程,我注册了两个activity,并在两个activity中各设置了一个按钮,可以互相跳转。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.out.println("MainActivity 按下了按钮");
startActivity(new Intent(MainActivity.this,SecondActivity.class));
}
});
System.out.println("MainActivity onCreate 执行了");
}
@Override
protected void onResume() {
super.onResume();
System.out.println("MainActivity onResume 执行了");
}
@Override
protected void onStart() {
super.onStart();
System.out.println("MainActivity onStart 执行了");
}
@Override
protected void onPause() {
super.onPause();
System.out.println("MainActivity onPause 执行了");
}
@Override
protected void onStop() {
super.onStop();
System.out.println("MainActivity onStop 执行了");
}
@Override
protected void onDestroy() {
super.onDestroy();
System.out.println("MainActivity onDestroy 执行了");
}
}
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.out.println("SecondActivity 按下了按钮");
startActivity(new Intent(SecondActivity.this,MainActivity.class));
}
});
System.out.println("SecondActivity onCreate 执行了");
}
@Override
protected void onResume() {
super.onResume();
System.out.println("SecondActivity onResume 执行了");
}
@Override
protected void onStart() {
super.onStart();
System.out.println("SecondActivity onStart 执行了");
}
@Override
protected void onPause() {
super.onPause();
System.out.println("SecondActivity onPause 执行了");
}
@Override
protected void onStop() {
super.onStop();
System.out.println("SecondActivity onStop 执行了");
}
@Override
protected void onDestroy() {
super.onDestroy();
System.out.println("SecondActivity onDestroy 执行了");
}
}
代码非常简单,就是在生命周期的每个位置,进行一次控制台的输出,那我们事不宜迟,现在就把代码跑一跑,让生命周期眼见为实。
控制台有很多其他语句,为了让大家看的方便,我把其中我们自己想要的输出截取出来,按照控制台输出的顺序排序。
Activity的跳转
在这里插入图片描述
从输出指令的执行顺序,我们可以清楚的看到,在完成activity的跳转过程中,先执行前一个activity的onPause方法,等到后一个activity执行到onResume阶段,显示在屏幕上时,前一个activity才会被停止。
返回键
如果我们按下返回键,从SecondActivity回到MainActivity时,情况有所不同,SecondActivity会在停止后被销毁。
在这里插入图片描述
可以看到其他过程与activity的跳转时一致的,只有在最后,回退键返回会销毁activity,而跳转只会停止activity,这个区别来源于安卓创建activity时使用的返回堆栈,具体在下文介绍,现在先看一下别的几种常见生命周期变化。
home键与应用间切换
在这里插入图片描述
HOME键返回桌面与应用间切换,跟activity跳转一样,并不会销毁activity,但要注意的是,后台运行时,activity可能会因为内存不足而被销毁
横竖屏切换
在这里插入图片描述
在横竖屏切换时,会触发配置更改,在配置更改的情况下,Activity 会被销毁并重新创建。
四、任务与返回栈
任务是用户在执行某项工作时与之互动的一系列 Activity 的集合。Activity 会按打开的顺序排列在一个返回堆栈中。
在当前 Activity 启动另一个 Activity 时,新的 Activity 将被推送到堆栈顶部并获得焦点。上一个 Activity 仍保留在堆栈中,但会停止。当 Activity 停止时,系统会保留其界面的当前状态。
当用户按返回按钮时,当前 Activity 会从堆栈顶部退出(该 Activity 销毁),上一个 Activity 会恢复(界面会恢复到上一个状态)。堆栈中的 Activity 永远不会重新排列,只会被送入和退出,在当前 Activity 启动时被送入堆栈,在用户使用返回按钮离开时从堆栈中退出。
这也是为什么我们使用返回键会销毁activity,而跳转不会的原因。
在这里插入图片描述任务是一个整体单元,当用户开始一个新任务或通过主屏幕按钮进入主屏幕时,任务可移至“后台”。在后台时,任务中的所有 Activity 都会停止,但任务的返回堆栈会保持不变,当其他任务启动时,当前任务只是失去了焦点。这样一来,任务就可以返回到“前台”,以便用户可以从他们离开的地方继续操作。
由于返回堆栈中的 Activity 不会被重新排列,如果您的应用允许用户从多个 Activity 启动特定的 Activity,系统便会创建该 Activity 的新实例并将其推送到堆栈中(而不是将该 Activity 的某个先前的实例移至堆栈顶部)。这样一来,应用中的一个 Activity 就可能被多次实例化(甚至是从其他任务对其进行实例化)
如果在上面代码演示时,多次重复进行activity的跳转,由于我们没有限制activity的新实例化,我们将会得到很多个相同的activity实例,这时我们使用返回键,会从这些相同的activity中逐层退出。
5. 小结
activity作为安卓最重要的四大组件之一,充分理解和掌握它的生命周期,对我们进行安卓开发非常重要,希望本文能让你对activity的生命周期有了更清晰的认识。