在使用Eclipse添加一个新的Activity时,系统会自动生成OnCreate()函数,而其他生命周期函数,例如OnStart() OnReSume()等它是不负责自动生成的,也因为这样,就会被很多开发者忽略,从而产生一些意想不到的错误。
在之前翻译的文章中,分别讲过各个生命周期函数的用法,这里整理一下。
下面是之前翻译的官方文档,里面包含了更详细的实例。
[Andriod官方训练教程]管理Activity的生命活动之开始一个Activity
[Andriod官方训练教程]管理Activity的生命活动之暂停和恢复一个Activity
[Andriod官方训练教程]管理Activity的生命活动之停止和重启一个Activity
[Andriod官方训练教程]管理Activity的生命活动之重新创建一个Activity
综述
一个Activity的生命周期图如下所示:
总体来说,一个Activity只有3种静止状态(其他状态都是瞬时的):
- Resumed 重新开始:在该状态下,activity是处于前台的,并且用户可以与它进行交互。(有时同样表示为"running"状态)
- Paused 暂停:在该状态下,activity部分的被另一个activity所掩盖——另一个在前台的activity是半透明的或者没有占据整个屏幕。暂停的activity不再接受用户输入并且不可以执行任何代码。
- Stopped 停止: 在该状态下,activity被完全隐藏并且对于用户是不可见的;它被认为是处于后台。当停止时,该activity实例和它的所有状态信息,例如成员变量将被保留,但是它不可以执行任何代码。
首先谈谈暂停(Paused)和停止(Stopped)状态。这两个都是静止状态,即应用程序可能长时间处于的状态。它们的不同主要有以下几个方面:
- 在通常的app使用中,前台的activity(Resumed状态)有时会被另一个可见的部件阻塞从而引起该activity发生暂停。例如,当某个应用程序请求打开蓝牙时会出现一个打开蓝牙的对话框,那么之前的activity就暂停了(Paused状态)。当你的activty进入暂停阶段(Paused状态)时,系统在你的Activity中调用onPause()方法,你可以重载这个方法来停止一些正在进行的动作,而这些动作不应该在暂停时继续进行(例如一个视频),或是在用户离开你的app时保留任何应该永久保存的信息。注意,当你的activity接收到一个onPause()调用时,它可能预示着activity将要被暂停一段时间,并且用户可能会返回你的activity。但是,这最可能表示用户正在离开你的activity。.当一个半透明的activity(例如之前提到的蓝牙开启对话框等)阻塞你的activity时,系统调用
onPause(),然后activity将在Paused状态等候。之后用户再次返回到activity(例如在蓝牙开启对话框出现后,选择了“是”或“否”,该对话框就会自动消失)时,系统将调用
onResume()。
- 一旦activity被完全阻塞并且不再可见,它将会停止(Stopped状态)。
了解系统何时停止(Stop)和重启(ReStart)你的activity也是很重要的,这确保你的用户可以感到你的app总是活跃的而不是丢失了他们的进程。在以下几种情况下你的activity需要被停止或是重启(请注意上图中需要调用的各种方法):
- 用户打开了“最近使用的应用程序”窗口,然后从你的app切换到另一个app。那么你的app里正在前台运行的activity就停止了。如果用户从主菜单里的开启图标或者“最近使用的应用程序”窗口返回到你的app,那activity就会重启。
- 用户在你的app里执行了一个开始新的activity的动作。那么当前的activity在第二个activity创建时就停止了。如果用户后来就按下了返回按钮,那么第一个activity就会重启。这里有个问题需要注意,返回按钮指的是手机下方自带的返回按钮,而不是创建一个activity的布局文件时自动创建的Up按钮。
首先我们来弄清楚两个按钮(Up和Back)的区别。
如图所示,当点击左方的按钮时,系统会将当前的activity弹出栈(一般来说,当一个应用启动时,会同时启动一个Task,然后在这个task里面按照堆栈的方式按照启动的顺序放入activity。举例来说,一个应用包含了A, B, C, D四个Activity. 用户点击activity的顺序是A, B, C, B, D, 那么在task里面,从栈第到栈顶依次会是A, B, C, B, D这5个activity的实例。 这个时候,在D界面上点击back(这里的back是指手机下方的返回按钮),D就会被弹出堆栈,android会显示activity B, 并且堆栈变为A, B, C, B),并且调用该activity的OnDestroy()方法,而之前的activity就会重启(只调用OnReStart()函数,而不会调用OnCreate()函数,之前它是处于暂停状态的,savedInstanceState也不为空,并保存了之前的一些信息)。但是,当点击右图时,系统会显示当前activity的父activity,它的父activity将会被重新创建,注意这里不是重新启动,它会调用OnCreate()方法来创建一个全新的实例,你也不可以使用savedInstanceState来企图初始化数据,因为此时这个实例是第一次被创建。如果在OnCreate()方法里你调用了类似于getIntent()这样的方法来得到它的父activity传来的数据,就有可能出现错误。这是因为,系统默认当点击Up按钮时,调用的方法是:
解决方法是将NavUtils.navigateUpFromSameTask(this)方法改为finish(),即:@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); }
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; } return super.onOptionsItemSelected(item); }
这样,当按下Up按钮后,当前的activity会自动销毁,从而就会显示上一个activity,起到up的作用,但又避免了重现创建一个新的父activity。 - 用户在使用你的app时接到了一个电话。
Activity类提供了两个生命周期方法,
onStop()
和onRestart(),它们允许你明确地控制你的activity该如何停止和重启。和暂停状态(只是局部的UI被阻塞)不同,停止状态确保UI对用户不再可见,而且用户的焦点在单独的一个activity上(或是完全是另一个单独的app)。因为当你的Activity实例停止时系统在内存中仍然保留了它,你可能不需要实现onStop()
和onRestart()(甚至是onStart()方法。对于大多数相对简单的activity,它们可以好好地停止和重启,而你可能只需要使用