Activity为Android4大组件之一。Activity作为Android的表现层(presentation layer),每个屏幕都是一个Activity(或由Activity继承而来),在Activity中使用View去构建图形化界面来展现信息和对用户的操作进行响应。
为了保护用户体验和对资源进行管理,需要理解Activity的生命周期。Activity的生命周期不是由Android Application来管理,而是由Android Runtime来管理。Activity的状态由其所在Activity Stack(该栈为后进先出栈)中的位置决定,在栈顶(即最后进栈)的Activity的状态是活动的(Active)。Activity的状态有4种:
Active: 当Activity在栈顶时,它是可见的(Visible)、有焦点的(Focused)、在前台的,对用户的操作进行响应。Android会尽可能保持它的Active状态,即使资源不够也会先杀掉栈底的Activity。当其它Activity变为Active时,这个Activity会变为paused状态。Paused: 在某些情况下,Activity还是可见的(Visible),但失去了焦点(如被部分覆盖),虽然看起来它好像是活动的,但它不能对用户的操作进行响应了。Android只有在极端缺资源的情况下才会杀这种状态的Activity。当一个Activity完全被覆盖时,它的状态变为stopped。Stopped: 当Activity完全不可见时(Not Visible),它的状态是停止的,但它仍然停驻在内存中并保持着各UI状态的数据。但当Android缺资源时,它是被杀掉的候选人。因此当状态要转为Stopped时,注意要保存好数据和UI的状态数据。Inactive: 当Activity被杀掉后且没有重启前,它的状态是inactive。这种状态的Activity会被从栈中清除,如果需要再次显示时需要重新启动。Activity的生命周期:
Full Lifetime: 从onCreate到onDestroy。但也有可能因为系统缺资源而在onPause或onStop阶段就把Activity销毁了。Visible Lifetime: 从onStart到onStop。在这个周期里,Activity可见(有可能是部分可见而没有焦点),在全生命周期(Full Lifetime)中可能有多个Visible Lifetime生命周期(如Activity多次从前台转到后台,然后再转回前台),在系统缺乏资源的时候,会出现不调用onStop就直接销毁Activity。Active Lifetime: 从onResume到onPause。在失去焦点时、其它Activity显示时、设备睡眠时,该生命周期都会结束。在调用onPause之前会先调用onSaveInstanceState,以供保存相关数据(如果不在onSaveInstanceState中保存数据,至少要重写onPause来保存数据,同时根据实际情况在onPause中还可能需要关闭Thread、Process、Broadcast Receiver、Service等)
Activity的主要骨骼代码:
public class MyActivityCircle extends Activity { private static final int MENU_QUIT = Menu.FIRST; /** 当Activity第一次启动时调用(或被销毁后再次启动时也会被调用) */ @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.main); } /** 在不可见后再次可见的开始时调用 */ protected void onRestart() { super.onRestart(); } /** 在Visible Lifecycle开始时调用 */ protected void onStart() { super.onStart(); } /** 在onStart()之后调用(但调用是有条件的,不是每次onStart之后都调用) */ protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } /** 在onRestoreInstanceState()之后调用,该方法主要是供系统作最后的初始化使用,一般不重写 */ protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); } /** 在Active Lifecycle开始时调用 */ protected void onResume() { super.onResume(); } /** 在onResume()之后调用,该方法主要是供系统在resume后作最后的构建使用,一般不重写 */ protected void onPostResume() { super.onPostResume(); } /** 在Active Lifecycle结束时(在onPause()前)调用,用于保存UI状态和数据 */ protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } /** 在Active Lifecycle结束时调用 */ protected void onPause() { super.onPause(); } /** 在Visible Lifecycle结束时调用 */ protected void onStop() { super.onStop(); } /** 在Full Lifetime结束时调用 */ protected void onDestroy() { Log.i(TAG, "onDestroy"); textEdit = null; super.onDestroy(); } /** 在Activity退出时调用 */ protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); } /** 在按MENU键时调用 */ public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, MENU_QUIT, Menu.NONE, "Quit"); return true; } /** 选Option Menu的菜单项时调用 */ public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); switch(item.getItemId()) { case MENU_QUIT: finish(); break; } return true; } /** 创建Activity的对话框时调用 */ protected Dialog onCreateDialog(int id) { return super.onCreateDialog(id); } /** 显示Dialog前调用 */ protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(); } /** 显示Dialog时调用 */ public final void showDialog(int id) { super.showDialog(); } }
补充:
大部分情况下,onSaveInstaceState()都会被调用,一个比较常见的不调用该方法的情况是手动按“返回”键。判断是否调用的标准主要是看“是否是系统已经获取到用户的允许”而停止活动,如用户手动按“返回”键、程序中调用finish()等则认为是允许了,而按“Home“键、切换横屏等则是未允许。而onRestoreInstanceState()则不常见,原因是只有在系统不经用户允许就“暴力”地销毁了Activity(原因主要是系统其它地方需要资源),再次回到这个Activity时会调用(如切换横屏时,系统会先销毁掉原来的Activity,然后再创建新的Activity,此时会调用onRestoreInstanceState)。这两点有说得更详细的地方:http://zhangkun716717-126-com.javaeye.com/blog/802131
各方法调用测试结果如下:
正常启动时: onCreate onStart onPostCreate onResume onPostResume 正常启动后按“返回”返回(相当于关闭了): onPause onStop onDestroy 正常启动后按Home键: onSaveInstanceState onPause onStop 按Home键后再双击应用进入: onRestart onStart onResume onPostResume 正常启动后切换为横屏: onSaveInstanceState onPause onStop onDestroy onCreate onStart onRestoreInstanceState onPostCreate onResume onPostResume
