[Android]管理Activity的生命周期
一、简要介绍
当用户开始,暂停,退出,重新进入一个APP的时候,APP中Activity实例在它生命周期的不同状态之间转换。比如当你第一次启动一个Activity时,Activity来到系统的前端获得用户焦点。在这个过程中,Android系统调用了一系列生命周期方法。如果用户启动或者切换到另一个APP,系统调用另外一系列的方法。
生命周期调用方法可以说明在用户离开或者重新进入Activity时,Activity执行哪些行为。
接下来我们将解释每一个Activity都有的生命周期方法,并且说明如何使用它们来完成用户需要的功能,并且在你不需要的时候不会占用过多的系统资源。
首先来看官方给出的Activity状态变化图。方框表示Activity可能处于的状态,箭头表示Activity在不同状态转化时会调用的函数。
除去未启动和被摧毁,Activity在运行时可能出现5种状态。分别是Created,Started,Resumed,Paused,Stopped。但是自由三种状态是稳定的,Activity会在这三种状态中停留一段时间。它们分别是:
Resumed 在这种状态下,Activity在屏幕中显示并且与用户正常交互。正常运行的状态。
Paused 在这种状态下,Activity被另一个Activity部分地遮挡,另一个Activity是半透明的或者并没有覆盖整个屏幕。Activity处于Paused状态时不能与用户交互,并且不能执行任何代码。
Stopped 在这种状态下,Activity被完全遮挡,对用户不可见。当Activity处于Stopped状态时,Activity实例和状态信息还存在,但是布恩执行任何代码。
另外两个状态(Created,Started)是只能存在非常短的时间,系统会很快地调用下一个生命周期方法时Activity进入下一个状态,比如系统调用onCreate()之后,很快地继续调用onStart(),之后继续调用onResume().
二、启动和停止
用户点击一个App的图标之后,系统在AndroidManifest.xml中寻找声明的主Activity,然后调用主Activity的onCreate()函数。通常onCreate()要被重载来定义Activity需要的变量,声明UI元素。
TextView mTextView; // Member variable for text view in the layout @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 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 mTextView = (TextView) findViewById(R.id.text_message); // Make sure we're running on Honeycomb or higher to use ActionBar APIs if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // For the main activity, make sure the app icon in the action bar // does not behave as a button ActionBar actionBar = getActionBar(); actionBar.setHomeButtonEnabled(false); } }
onCreate()完成调用之后,系统很快继续调用onStart()和onResume(),Activity不会停在Created和Started的状态。在onStart()调用完成之后,Activity对用户可见,之后系统继续调用onResume(),然后Activity停留在Resume状态,也就是正常运行的状态。直到一些事情发生改变这个状态。
Activity生命周期中第一个被调用的是onCreate(),而最后一个被调用的是onDestory()。这个方法被调用表示Activity实例从系统中被完全地去除。
大多数应用不需要西线这个方法,因为大多数局部类引用由Activity自动回收,剩下的回收清理工作需要在onPause()和onStop()中完成,但是如果Activity中有后台线程或者其他可能引起内存泄漏的资源,需要在onDestory()中回收。
比如:
@Override public void onDestroy() { super.onDestroy(); // Always call the superclass // Stop method tracing that the activity started during onCreate() android.os.Debug.stopMethodTracing(); }
三、暂停和恢复
当Activity被不完全遮挡时会调用onPause()进入Paused状态。
开发者需要重载onPause()来停止正在运行的行为或者保存一些需要永久保存的信息。
开发者需要在onPause()函数中实现的内容有:
1.停止动画挥着其他正在进行的消耗CPU的行为
2.保存一些变化(用户需要保存的变量)比如邮件的草稿。
3.释放系统资源,比如broadcast receiver,传感器句柄(比如GPS),或者其他耗电的资源。
比如,如果你的应用使用的照相机,那onPause()方法是一个很好的释放照相机的地方。
@Override public void onPause() { super.onPause(); // Always call the superclass method first // Release the Camera because we don't need it when paused // and other activities might need to use it. if (mCamera != null) { mCamera.release() mCamera = null; } }
一般来说,onPause()中不需要保存用户变量,onPause()中需要保存的是应该自动保存的变量,比如邮件草稿。同时,onPause()中要避免CPU密集的工作,比如写入数据库,因为这会减慢转换到下一个Activity的视觉过程。CPU密集的保存工作应该放在onStop()中。
Activity从Paused状态恢复到Resumed状态时会调用onResume()。
Activity每次来到前端的时候都会调用onResume()函数,包括第一次创建应用的时候,因此onResume()中应该初始化onPause()中释放的资源并且执行Activity每次获得用户焦点都要执行的代码。
下面onResume()的例子是onPause()的逆过程,初始化在onPause()中释放的camera
@Override public void onResume() { super.onResume(); // Always call the superclass method first // Get the Camera instance as the activity achieves full user focus if (mCamera == null) { initializeCamera(); // Local method to handle camera init } }
四、停止和重新开始
正确地停止和重新开始Activity是一个很重要的过程,这能确保你的app一直都在,没有丢失数据。在下面这些情况下,Activity会被停止或重新开始。
1.用户切换的另外一个APP,当前APP的Activity会并停止。如果用户重新切换到当前APP,Activity会被重新开始。
2.用户执行了操作启动了当前APP的另外一个Activity,当前Activity会被停止,如果用户按了返回键,当前Activity被重新启动。
3.用户在使用你的APP时接到一个电话。
Activity类提供了两个生命周期方法,onStop()和onRestart(),允许程序员处理Activity是如何被停止和重新启动的。
Activity处于Stopped状态时系统可能直接杀掉进程而不调用onDestory(),所以onStop()中要释放所有可能泄漏的资源。同时onStop()中要执行CPU密集的操作,比如写入数据库等。
当Activity被停止时,Activity对象仍然在内存中等待重新调用。所以在Activity重新启动的时候不需要重新初始化组件。系统会保留每一个组件的当前状态,比如编辑框(EditText)中输入的文字。
当Activity从Stopped状态回到前台的时候,系统会连续调用onRestart()和onStart().
通常来说,使用onStart()方法作为onStop()的逆操作,而在onRestart()中不进行任何操作。因为Activity只有从Stopped状态回到前台才会调用onRestart(),而从任何状态进入前台都会调用onStart()。
当系统摧毁你的Activity时,它会调用onDestory()。因为在onStop()中已经释放大部分的资源,所以调用onDestory()时,已经不需要做很多事了,但是onDestory()是最后一个释放资源的机会,所以在onDestory()中要确保所有资源都被释放,比如额外进程和后台运行的行为。
翻译自http://developer.android.com/training/basics/activity-lifecycle/index.html