主要内容来自官方文档:Activity
public class Activity
extendsContextThemeWrapper
implementsLayoutInflater.Factory2,Window.Callback,KeyEvent.Callback, View.OnCreateContextMenuListener, ComponentCallbacks2
Activity是一个用户能独立、专心处理的事物。几乎所有Activity都与用户交互,所以Activity类会通过调用setContentView(View)来创建一个可以用来放置你的UI的窗口。尽管Activity经常以全屏窗口的形式呈现给用户,但它们也有其他的使用方法:作为浮动窗口(通过一个设置了WindowIsFloating的主题)或者嵌入其他Activity中(使用ActivityGroup)。
这里有两个几乎所有Activity子类都会实现的方法:
为了使用Context.startActivity(),所有Activity类型都必须在包的AndroidManifest.xml中存在对应的
系统中的Activity以Activity栈的形式管理。当一个新Activity被启动后,它会被放置在栈的顶部并成为正在运行的Activity -- 它之前的Activity在栈中总是处于它的下面,并且直到新Activity退出时,它才会重新返回到前台。
一个Activity实质上有四中状态:
接下来的图展示了一个Activity的重要的状态路径图:
其中有三个关键的回路,我们在监测自己的Activity也许会感兴趣:
接下来的Activity接口定义了一个Activity的完整生命周期。它们是一组“钩子”接口,你可以覆写它们,以便在Activity改变状态时做一些相应的工作。所有的Activity都会实现onCreate(Bundle)来完成它们的初始化步骤。许多Activity也会实现onPause()方法来提交变化的数据或者做一些工作以准备停止和用户交互。在实现这些方法时,你总是需要先调用父类中的该同名方法。
public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
通常情况下,贯穿Activity生命周期的一个回调转移过程如下所示:
Method | Description | Killable? | Next | ||
---|---|---|---|---|---|
onCreate() |
Activity第一创建时调用。我们应该在该函数中做一般的初始化工作,如创建各个View对象、为列表绑定数据等。如果有的话,这个方法总是会提供你一个包含之前Activity冻结状态的Bundle对象。onStart()方法总是在该方法之后。 | No | onStart() |
||
onRestart() |
在Activity停止之后,重新启动之前被调用。它之后总是调用onStart()方法。 |
No | onStart() |
||
onStart() |
在Activity即将对用户可见时调用。如果Activity即将前台显著位置,那它之后是onResume()方法;如果Activity被隐藏,那它之后是onStop()方法。 | No | onResume() or onStop() |
||
onResume() |
当Activity即将开始和用户交互时,它会被调用。此时,你的Activity会在栈的最顶端,用户可以对它进行输入操作。它之后总是onPause()调用。 | No | onPause() |
||
onPause() |
当系统开始(esume一个之前的Activity时,它会被调用。典型的,我们一般在此执行保存数据、关闭动画或其他某些消耗CPU资源的动作。该方法的执行必须非常快速,因为下一个Activity只会在该方法完成并返回后,才会被resume。如果Activity接下来返回到屏幕前台,那么它接下来是onResume()方法;如果Activity变成对用户不可见,那它之后是onStop()方法。 | Pre-HONEYCOMB |
onResume() oronStop() |
||
onStop() |
当一个Activity不再对用户可见时,该方法会被调用;因为另一个Activity会被resume并覆盖到它之上。这个方法也会在当一个Activity正在被启动,但此时另一个存在的Activity被直接处理到它之前,或者这个Activity即将被销毁时调用。如果一个Activity即将重新回到前台与用户交互,那它之后是onRestart()调用;如果这个Activity即将被销毁,那它之后是onDestroy()调用。 | Yes | onRestart() oronDestroy() |
||
onDestroy() |
这是你的Activity在销毁之前,你能接收到的最后一个函数调用。当用户调用finish(),或者系统为了节省空间,需要暂时销毁该Activity实例时,你的Activity才会被销毁。你可以通过isFinishing()方法来区分这两种场景。 | Yes | nothing |
注意表中的“Killable”一栏 -- 对于那些被标记为“killable”的方法,在这些方法返回之后,持有该Activity的进程可能会在不执行任何其他一行该Activity的代码的情况下被系统杀死。因此,你需要在onPause()中保存任何修改过的并需要保存的数据。除此之外,onSaveInstanceState(Bundle)会在该Activity转变成后台状态之前被调用,这允许你在给定的Bundle中,保存任何你Activity中的动态实例状态信息;之后当该Activity需要再次被创建时,你可以在onCreate(Bundle)中重新接收它们。我们需要注意的一点是,我们应该在onPause(),而不是onSaveInstanceState(Bundle)中,保存那些持久性数据;因为后者并不是生命周期回调的一部分,所以它并不会在文档中描述的每一个场景中都被调用。
对于那些没有被标记为“killable”的方法,Activity所在的进程在该方法调用开始并在它返回之后,都不会被系统杀死。因此,举个例子:一个Activity在onPause()之后,onResume()调用之前,它都处于进程可被杀死的状态。
startActivity(Intent)方法可以用来启动Activity,它将会被放置在Activity栈的顶端。方法只需要一个Intent参数,它描述了需要被执行的Activity。
有时候你会想要从一个结束的Activity中得到一个返回结果。例如,你会开启一个Activity让用户从联系人列表中选择一个人;当该Activity结束时,让它返回被选中的结果。为了实现这种情况,你需要调用startActivityForResult(Intent, int)版本,它附带了一个定义此次调用请求的int型参数。该调用结果会通过onActivityResult(int, int, Intent)方法返回。
当一个Activity退出时,它可以调用setResult(int)向它的父Activity返回数据。它必须总是提供一个结果码,这可以是标准定义结果码 RESULT_CANCEELD/RESULT_OK,或者任何从RESULT_FIRST_USER开始的客户值。除此之外,这个Activity可以随意返回一个包含任何它期望的数据的Intent给父Activity。所有的这些信息都会在父Activity的onActivityResult()函数中出现,同时它也会附带之前提供的对此次调用的请求码。
如果子Activity由于诸如崩溃的原因运行失败了,它的父Activity将会收到一个带有RESULT_CANCELED码值的结果。
public class MyActivity extends Activity {
...
static final int PICK_CONTACT_REQUEST = 0;
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
// When the user center presses, let them pick a contact.
startActivityForResult(
new Intent(Intent.ACTION_PICK,
new Uri("content://contacts")),
PICK_CONTACT_REQUEST);
return true;
}
return false;
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
// A contact was picked. Here we will just display it
// to the user.
startActivity(new Intent(Intent.ACTION_VIEW, data));
}
}
}
}
Android系统会尝试尽可能地保存应用程序进程,但是当系统内存很低时,它最终也会去移除一些老的进程。正如Activity生命周期部分所描述的,决定移除哪一个进程跟用户与进程的交互状态密切相关。一般情况下,基于运行其中的Activity,一个进程可以有4种状态,下面以重要性为序列出。系统会按重要性从低(最后一个)到高(第一个)的顺序杀死应用进程。
启动一个当它结束时你期望从它得到一个返回结果的Activity。当启动的Activity退出时,你的onActivityResult()方法会附requestCode参数被调用。如果你调用时使用的requestCode是负值,那它效果等同于startActivity(Intent)。
需要注意的是,该方法只有当你使用被定义成会返回结果的Intent协议时才应当被使用。在其他协议中(如ACTION_MAIN或者ACTION_VIEW),你也许并不会如期望地那样得到一个结果。如果你启动Activity时使用了FLAG_ACTIVITY_NEW_TASK标志,那么它将不会运行在你当前的Activity栈中,你会立即收到一个CANCELED结果。
作为一个特殊的例子,如果你在Activity的onCreate()/onResume()方法中,使用了一个大于等于0的requestCode参数去调用startActivityForResult();此时你的窗口只会在从启动的Activity中得到一个结果之后,它才会显示出来。这样可以避免当重定向到其他Activity时,屏幕会产生可见的闪烁。
Parameters | |
---|---|
intent |
Intent : The intent to start. |
requestCode |
int : If >= 0, this code will be returned in onActivityResult() when the activity exits. |
options |
Bundle : Additional options for how the Activity should be started. See startActivity(Intent, Bundle) Context.startActivity(Intent, Bundle)} for more details. This value may be |
该函数一般与setResult(int requestCode, Intent data)结合使用。
用来得到一个Activity被杀死之前的某些状态,确保在该Activity被重新启动时,在onCreate(Bundle)/onRestoreInstanceState(Bundle)中,它可以根据Bundle中的信息重新恢复到被杀死之前的状态(Bundle对象通常会被同时传递给这两个方法)。
这个方法一般在某个Activity即将被杀死之前调用,所以将来当它重新回归时,它可以恢复它之前的状态。例如,Activity B被启动,并处在Activity A的前面,某个时间点为了回收资源,Activity A被杀死了;Activity会有一个通过该方法保存当前它的用户接口当前状态的机会,所以当用户重新返回到Activity A时,它的用户接口状态可以通过onCreate(Bundle)/onRestoreInstanceState(Bundle)接口重新得到恢复。
不要对该方法和Activity生命周期回调函数产生困惑(如onPause(),它总是在Activity被转入后台或即将被销毁时调用;如onStop(),总是在Activity销毁之前调用)。一个onPause()、onStop()方法会被调用,而onSaveInstanceState(Bundle)不会被调用的例子就是:用户手动将Activity A操作到Activity B之前;此时没有必要在Activity B上调用onSaveInstanceState()函数,因为此时没有需要保存的特定信息,所以系统就会避免去调用它。一个onPause()被调用,而onSaveInstanceState()不会的场景就是Activity B被启动,并且运行在Activity A之前;如果Activity A在Activity B的生命周期内没有被系统杀死,那么它的onSaveInstanceState()不会被调用,因为Activity A此时的用户接口状态并不会改变。
如果onSaveInstanceState()被调用,那么它会发生在onStop()之前。我们无法保证它的调用是否会发生在onPause()之前或之后。
当一个Activity被重新初始化为之前的状态时(saveInstanceState提供),它会在onStart()之后被调用。大多数时候,我们会简单实现onCreate(Bundel)来恢复Activity的状态;但有些时候在所有初始化工作都完成后,再在该函数中进行状态恢复,或者允许子类自己决定如何使用函数的默认实现,都是很方便的。该函数的默认实现就是将Activity的任何View状态恢复到之前onSaveInstanceState(Bundle)被调用时这些View最后冻结的状态那样。
该函数在onStart()和onPostCreate(Bundle)之间被调用。