了解Activity生命周期
当用户浏览,退出和返回您的应用时,您应用中的activity实例会在其生命周期中的不同状态中进行转换。 Activity类提供了许多回调,允许activity知道状态已更改:系统正在创建,停止或恢复activity,或者销毁activity所在的进程。
在生命周期回调方法中,您可以声明用户离开并重新进入activity时activity的行为方式。 例如,如果您正在构建流式视频播放器,则可能会暂停视频并在用户切换到另一个应用时终止网络连接。 当用户返回时,您可以重新连接到网络并允许用户从同一位置恢复视频。换句话说,每个回调允许您执行适合于给定状态更改的特定工作。在正确的时间做正确的工作并正确处理过渡使您的应用程序更加强大和高效。 例如,生命周期回调的良好实现可以帮助确保您的应用程序避免:
- 如果用户在使用您的应用时接到电话或切换到其他应用,则会崩溃。
- 当用户不主动使用它时,消耗宝贵的系统资源。
- 如果用户离开您的应用并稍后返回,则会丢失用户的进度。
- 当屏幕在横向和纵向之间旋转时,会崩溃或丢失用户的进度。
本文档详细说明了活动生命周期。该文档首先描述了生命周期范例。 接下来,它解释了每个回调:执行时内部发生的事情,以及在它们期间应该实现的内容。 然后简要介绍了activity状态与进程被系统杀死的漏洞之间的关系。最后,它讨论了与活动状态之间的转换相关的几个主题。
有关处理生命周期的信息(包括有关最佳实践的指导),请参阅使用生命周期感知组件处理生命周期和保存UI状态。要了解如何使用与体系结构组件结合的活动来构建强大的,生产质量的应用程序,请参阅应用程序体系结构指南。
Activity-生命周期概念
为了在活动生命周期的各个阶段之间导航转换,Activity类提供了六个回调的核心集:onCreate(),onStart(),onResume(),onPause(),onStop()和onDestroy()。 当activity进入新状态时,系统会调用每个回调。
图1展示了这种范例的直观表示。
图1.活动生命周期的简化图示。
当用户开始离开activity时,系统调用方法来拆除activity。在某些情况下,这种拆除只是部分的; activity仍然驻留在内存中(例如当用户切换到另一个应用程序时),并且仍然可以返回到前台。 如果用户返回该activity,则activity将从用户停止的位置恢复。系统杀死给定进程的可能性及其中的activity取决于当时activity的状态。activity状态和从内存中弹出提供了有关状态与弹出漏洞之间关系的更多信息。
根据activity的复杂程度,您可能不需要实现所有生命周期方法。 但是,了解每一个并实施确保您的应用程序按用户期望的方式运行的内容非常重要。
本文档的下一部分提供了有关用于处理状态之间转换的回调的详细信息。
生命周期回调
本节提供有关在activity生命周期中使用的回调方法的概念和实现信息。
某些操作(如调用setContentView())属于活动生命周期方法本身。 但是,实现依赖组件操作的代码应放在组件本身中。要实现此目的,您必须使依赖组件生命周期可识别。 请参阅使用生命周期感知组件处理生命周期,以了解如何使您的从属组件生命周期感知。
onCreate()
在activity创建时,活动进入创建状态。 在onCreate()方法中,您执行基本的应用程序启动逻辑,该逻辑在活动的整个生命周期中只应发生一次。 例如,onCreate()的实现可能会将数据绑定到列表,将activity与ViewModel相关联,并实例化一些类范围变量。 此方法接收参数savedInstanceState,该参数是包含activity先前保存状态的Bundle对象。 该参数是包含activity先前保存状态的Bundle对象。 如果activity以前从未存在过,则Bundle对象的值为null。
如果您有一个生命周期感知组件连接到您的活动的生命周期,它将收到ON_CREATE事件。 将调用使用@OnLifecycleEvent注释的方法,以便您的生命周期感知组件可以执行创建状态所需的任何设置代码。
以下onCreate()方法示例显示了activity的基本设置,例如声明用户界面(在XML布局文件中定义),定义成员变量以及配置某些UI。在此示例中,通过将文件的资源ID R.layout.main_activity传递给setContentView()来指定XML布局文件。
KOTLIN
lateinit var textView: TextView // some transient state for the activity instance var gameState: String? = null override fun onCreate(savedInstanceState: Bundle?) { // call the super class onCreate to complete the creation of activity like // the view hierarchy super.onCreate(savedInstanceState) // recovering the instance state gameState = savedInstanceState?.getString(GAME_STATE_KEY) // set the user interface layout for this activity // the layout file is defined in the project res/layout/main_activity.xml file setContentView(R.layout.activity_main) // initialize member TextView so we can manipulate it later textView = findViewById(R.id.text_view) } // This callback is called only when there is a saved instance that is previously saved by using // onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore // other state here, possibly usable after onStart() has completed. // The savedInstanceState Bundle is same as the one used in onCreate(). override fun onRestoreInstanceState(savedInstanceState: Bundle?) { textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY) } // invoked when the activity may be temporarily destroyed, save the instance state here override fun onSaveInstanceState(outState: Bundle?) { outState?.run { putString(GAME_STATE_KEY, gameState) putString(TEXT_VIEW_KEY, textView.text.toString()) } // call superclass to save any view hierarchy super.onSaveInstanceState(outState) }
JAVA
TextView textView; // some transient state for the activity instance String gameState; @Override public void onCreate(Bundle savedInstanceState) { // call the super class onCreate to complete the creation of activity like // the view hierarchy super.onCreate(savedInstanceState); // recovering the instance state if (savedInstanceState != null) { gameState = savedInstanceState.getString(GAME_STATE_KEY); } // set the user interface layout for this activity // the layout file is defined in the project res/layout/main_activity.xml file setContentView(R.layout.main_activity); // initialize member TextView so we can manipulate it later textView = (TextView) findViewById(R.id.text_view); } // This callback is called only when there is a saved instance that is previously saved by using // onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore // other state here, possibly usable after onStart() has completed. // The savedInstanceState Bundle is same as the one used in onCreate(). @Override public void onRestoreInstanceState(Bundle savedInstanceState) { textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY)); } // invoked when the activity may be temporarily destroyed, save the instance state here @Override public void onSaveInstanceState(Bundle outState) { outState.putString(GAME_STATE_KEY, gameState); outState.putString(TEXT_VIEW_KEY, textView.getText()); // call superclass to save any view hierarchy super.onSaveInstanceState(outState); }
作为定义XML文件并将其传递给setContentView()的替代方法,您可以在activity代码中创建新的View对象,并通过将新视图插入ViewGroup来构建视图层次结构。 然后,通过将根ViewGroup传递给setContentView()来使用该布局。 有关创建用户界面的更多信息,请参阅用户界面文档。
您的activity不在“已创建”状态。onCreate()方法完成执行后,activity进入Started状态,系统快速连续调用onStart()和onResume()方法。 下一节将介绍onStart()回调。
onStart()
当活动进入Started状态时,系统将调用此回调。onStart()调用使activity对用户可见,因为应用程序准备activity以进入前台并变为交互式。例如,此方法是应用程序初始化维护UI的代码的位置。
当活动进入启动状态时,任何与活动生命周期相关的生命周期感知组件都将收到ON_START事件。
onStart()方法非常快速地完成,并且与Created状态一样,活动不会保持驻留在Started状态。 一旦此回调结束,活动就进入Resumed状态,系统将调用onResume()方法。
onResume()
当activity进入Resumed状态时,它进入前台,然后系统调用onResume()回调。这是应用程序与用户交互的状态。 该应用程序保持这种状态,直到某些事件成为焦点离开应用程序。例如,这样的事件可能是接收电话,用户导航到另一个活动,或者设备屏幕关闭。
当activity进入恢复状态时,任何与activity生命周期相关的生命周期感知组件都将收到ON_RESUME事件。 这是生命周期组件可以启用任何需要在组件可见且在前台运行时运行的功能的位置,例如启动摄像头预览。
当发生中断事件时,activity进入Paused状态,系统调用onPause()回调。
如果活动从Paused状态返回Resumed状态,则系统再次调用onResume()方法。因此,您应该实现onResume()来初始化在onPause()期间释放的组件,并执行每次活动进入Resumed状态时必须进行的任何其他初始化。
以下是在组件收到ONRESUME事件时访问摄像头的生命周期感知组件的示例:
KOTLIN
class CameraComponent : LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun initializeCamera() { if (camera == null) { getCamera() } } ... }
JAVA
public class CameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void initializeCamera() { if (camera == null) { getCamera(); } } ... }
一旦LifecycleObserver收到ON_RESUME事件,上面的代码就会初始化摄像机。但是,在多窗口模式下,即使活动处于暂停状态,您的activity也可能完全可见。例如,当用户处于多窗口模式并点击不包含您的activity的其他窗口时,您的activity将移至暂停状态。如果您希望仅在应用程序恢复时活动相机(在前景中可见且活动),则在上面演示的ON_RESUME事件后初始化相机。如果您想在activity暂停但是可见时(例如在多窗口模式下)保持相机处于活动状态,则应在ON_START事件后初始化相机。但请注意,在activity暂停时让相机处于活动状态可能会在多窗口模式下拒绝将相机访问另一个已恢复的应用程序。有时可能需要在activity暂停时保持相机处于活动状态,但如果这样做,实际上可能会降低整体用户体验。仔细考虑生命周期中的哪个位置更适合在多窗口环境中控制共享系统资源。要了解有关支持多窗口模式的更多信息,请参阅多窗口支持。
无论您选择在哪个构建事件中执行初始化操作,请确保使用相应的生命周期事件来释放资源。如果在ON_START事件之后初始化某些内容,则在ON_STOP事件之后释放或终止它。 如果在ON_RESUME事件之后初始化,则在ON_PAUSE事件之后释放。
请注意,上面的代码片段将相机初始化代码放在生命周期感知组件中。 您可以将此代码直接放入活动生命周期回调中,例如onStart()和onStop(),但不建议这样做。将此逻辑添加到独立的生命周期感知组件中,您可以跨多个activity重用该组件,而无需重复代码。请参阅使用生命周期感知组件处理生命周期以了解如何创建生命周期感知组件。
onPause()
- 系统将此方法称为用户离开您的acitivity的第一个指示(尽管并不总是意味着acitivity正在被销毁); 它表示activity不再在前台(尽管如果用户处于多窗口模式,它仍然可见)。使用onPause()方法暂停或调整在“activity”处于“暂停”状态时不应继续(或应继续适度)的操作,并且您希望很快恢复。activity可能进入此状态的原因有多种。 例如:
- 某些事件会中断应用程序执行,如onResume()部分所述。 这是最常见的情况。在Android 7.0(API级别24)或更高版本中,多个应用程序以多窗口模式运行。由于只有一个应用程序(窗口)可以随时关注,系统会暂停所有其他应用程序。
- 将打开一个新的半透明acitivity(如对话框)。 只要activity仍然部分可见但不是焦点,它仍然暂停。
当activity进入暂停状态时,任何与activity生命周期相关的生命周期感知组件都将收到ON_PAUSE事件。 这是生命周期组件可以停止在组件不在前台时不需要运行的任何功能的地方,例如停止相机预览。
您还可以使用onPause()方法释放系统资源,处理传感器(如GPS),或者在您的activity暂停且用户不需要时可能影响电池寿命的任何资源。 但是,如上面onResume()部分所述,如果处于多窗口模式,Paused activity仍然可以完全可见。 因此,您应该考虑使用onStop()而不是onPause()来完全释放或调整与UI相关的资源和操作,以更好地支持多窗口模式。
下面对On_PAUSE事件做出反应的LifecycleObserver示例是上面ON_RESUME事件示例的对应示例,释放了在收到ON_RESUME事件后初始化的摄像头:
KOTLIN
class CameraComponent : LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun releaseCamera() { camera?.release() camera = null } ... }
JAVA
public class JavaCameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void releaseCamera() { if (camera != null) { camera.release(); camera = null; } } ... }
注意,上面的代码片段在LifecycleObserver收到ON_PAUSE事件后放置相机释放代码。 如前所述,请参阅使用生命周期感知组件处理生命周期以了解如何创建生命周期感知组件。
onPause()执行非常简短,并不一定要有足够的时间来执行保存操作。 因此,您不应使用onPause()来保存应用程序或用户数据,进行网络调用或执行数据库事务; 在方法完成之前,此类工作可能无法完成。相反,您应该在onStop()期间执行重负载关闭操作。有关在onStop()期间执行的合适操作的更多信息,请参阅onStop()。 有关保存数据的更多信息,请参阅保存和恢复activity状态。
完成onPause()方法并不意味着activity离开Paused状态。 相反,activity保持在此状态,直到activity恢复或变得对用户完全不可见。如果activity恢复,系统将再次调用onResume()回调。 如果活动从Paused状态返回到Resumed状态,系统会将Activity实例驻留在内存中,在系统调用onResume()时调用该实例。 在这种情况下,您无需重新初始化在任何导致Resumed状态的回调方法期间创建的组件。 如果activity变得完全不可见,则系统调用onStop()。下一节讨论onStop()回调。
onStop()
了解Activity生命周期的更多相关文章
- [转]: 两分钟彻底让你明白Android Activity生命周期(图文)!
转自:http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在前 ...
- Activity生命周期(深入理解)
今天看到一篇大神总结Activity的文章,内容甚为详细,特此转载http://www.cnblogs.com/lwbqqyumidi/p/3769113.html Android官方文档和其他不少资 ...
- Android Activity生命周期
从android api文档摘抄出来的activity生命周期图如下: Activity有如下四种状态 a.活动状态 activity处于屏幕前台,获取到了焦点可以和用户进行交互,同一时刻只有一个a ...
- Android Activity生命周期详讲
管理 Activity 生命周期 通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要. Activity 的生命周期会直接受到 Activity 与其他 Activit ...
- android Activity生命周期(设备旋转、数据恢复等)与启动模式
1.Activity生命周期 接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行.暂停和停止三种状态,onCreate.onStart.onResume.o ...
- android开发------Activity生命周期
这几天工作比较忙,基本没有什么时间更新播客了. 趁着今晚有点时间,我们来简单说一下什么是Activity生命周期和它们各阶段的特征 什么是生命周期 在还没有接触android开发的时候,听到有人说Ac ...
- 安卓activity生命周期
相信不少朋友也已经看过这个流程图了,也基本了解了Activity生命周期的几个过程,我们就来说一说这几个过程. 1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法, ...
- Activity生命周期 onCreate onResume onStop onPause (转)
Android应用开发提高系列(6)——Activity生命周期 onCreate 和 onResume 在程序启动时候都会启动, 所有有些需要在onCreate onResume中都要实现的功能,之 ...
- Android总结篇系列:Activity生命周期
Android官方文档和其他不少资料都对Activity生命周期进行了详细介绍,在结合资料和项目开发过程中遇到的问题,本文将对Activity生命周期进行一次总结. Activity是由Activit ...
- Android体系结构及activity生命周期
Android的系统架构采用了分层架构的思想,如图1所示.从上层到底层共包括四层,分别是应用程序程序层.应用框架层.系统库和Android运行时和Linux内核 Android的系统架构图 每层 ...
随机推荐
- linux 笔记 第一天
打开终端:ctrl+alt+t 清屏:ctrl+l 在终端在退出锁定:ctrl+c 目录:又称为文件夹,是包含所有的文件 目录创建规则: 1.大小是256 2.不能包含特殊字符 3.见名知义 路径:是 ...
- mysql----------mysql的一些常用命令
1.查询一张表中某个字段重复值的记录 select id,cert_number from (select id,cert_number,count(*)as n from 表明 group by c ...
- JavaScript命名规范基础及系统注意事项
前端代码中的自定义变量命名 命名方法: 1.驼峰 2.下划线连接 对于文件名,我们一般采用小写字母+下划线的形式 为什么?因为在window下a ...
- Go 初体验 - 并发与锁.3 - 竞态
竞态,就是多个协程同时访问临界区,由并发而产生的数据不同步的状态. 这个说的有点low,没办法,我就是这么表达的,官方的请度娘. 先上代码: 输出: 为何不是1000?就是因为竞态,发生竞态后,最终的 ...
- android sdk 安装 配置
下载android sdk manager:http://dl.google.com/android/installer_r24.4.1-windows.exe 打开sdk manager 在tool ...
- python 开发练习之 监控
本节内容 为什么要做监控? 常用监控系统设计讨论 监控系统架构设计 监控表结构设计 为什么要做监控? –熟悉IT监控系统的设计原理 –开发一个简版的类Zabbix监控系统 –掌握自动化开发项目的程序设 ...
- 【winform】serialPort 串口
一. 1.串口通信简单实现 该来的总会来的,学做硬件的,串口这个东西必须得门清. 俗话说的好,不会做串口助手的电子工程师不是好程序员.
- Oarcle之序列
序列:是一种数据库对象,用来自动产生一组唯一的序号: 序列:是一种共享式的对象,多个用户可以共同使用序列中的序号. 创建序列 create sequence seq_emp_temp incremen ...
- 使用特性将数据库返回的datatable转换成对象列表
public class ColumnMapAttribute : Attribute { private readonly string _name; public ColumnMapAttribu ...
- GCOV&LCOV&GCOVR入门
索引 一.概述 二.关于gcov的安装 三.代码覆盖率测试(以GCOV为例) 1.编译源代码 2.运行可执行程序 3.通过gcov指令生成代码覆盖率报告 四.生成更全面.直观的代码覆盖率报告 1.LC ...