本篇内容:
1、Activity的状态及状态间的转换
2、Activity栈
3、Activity启动模式
4、Activity生命周期
Activity即提供用户与屏幕交互的应用程序组件,如拨打电话、拍照、发送电子邮件或浏览地图。简单来说,一个Activity即一个布满整个窗口或者悬浮于其他窗口上的交互界面。通常一个应用程序包含有多个Activity,其中有一个Activity被指定为MainActivity,启动应用程序时将首先启动MainActivity。
Activity的状态及状态间的转换
在android中,Activity有四种基本状态:
运行状态:一个新的Activity启动入栈后,处于屏幕的最前端,处于Activity栈的最顶端,此时它对用户可见且可交互
暂停状态:当Activity被一个透明或者dialog覆盖,这时,它仍然对用户可见但是却不能和用户交互
停止状态:当Activity被另外一个Activity完全覆盖时,失去焦点,且对用户不可见,但是系统仍然保留着它的状态信息和成员信息
死亡状态:当Activity被系统杀死,内存已被回收或者该Activity还没有启动
这4种状态随着一个Activity的创建、销毁或者另外一个Activity的创建而不停的转换,这种转换的发生依赖于用户对应用程序的操作,下图简单的说明了这4种状态发生转换的时机和条件:
图1、Activity间的状态转换
Activity栈
Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示:
图 2. Activity 的状态与它在栈中的位置关系
如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置。
Activity启动模式
Activity共4种启动模式,在创建Activity时通过如下方式指定:
- <activity android:name=".MainActivity" android:launchMode="standard"/>
其中standard模式为Activity默认的启动模式,其他几种启动模式以及相互间的区别如下:
standard:每次激活Activity时都会创建Activity实例,并放入Activity栈中
singleTop:如果Activity栈顶正好存在该Activity实例,就重用该实例,否则将会重新创建一个Activity实例并放入栈顶(只要该实例未在栈顶就重新创建)
singleTask:如果Activity栈中存在该Activity实例,就重新该实例,并且将该实例重新放入栈顶,为了让其移动到栈顶,原来在其之上的其他Activity实例将被移除栈。如果栈中不存在该Activity实例就重新创建实例
singleInstance:在一个新的Activity栈中创建该Activity实例,并让多个应用共享该栈中的Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用在激活该Activity时都会重用该栈中的实例。相当于多个应用共享一个应用,只要任何一个应用激活该Activity就都会进入同一个应用中。
Activity生命周期
Android在Activity类中定义了一系列与生命周期相关的方法,通过调用这些方法来实现Activity生命周期内各种状态间的转换。
- public class MyActivity extends Activity {
- protected void onCreate(Bundle savedInstanceState);
- protected void onStart();
- protected void onResume();
- protected void onPause();
- protected void onStop();
- protected void onDestroy();
- }
一个完整的生命周期从调用onCreate()开始,到调用onDestroy()结束。一般情况下,我们重写onCreate()作为应用程序的一个入口点,在这里做一些初始化数据、设置用户界面等工作。大多数情况下,我们都要在这里从 xml 中加载设计好的用户界面。重写onDestroy()来释放资源。
一个可见的生命周期是从调用onStart()开始,到调用onStop()结束。在这个生命周期内,用户可以看到该Activity展示在手机屏幕上且可与其交互。例如:当一个新的Activity覆盖在A Activity上,且A Activity不可见了,这时候A的onStop()将被调用。
一个前景(foreground)生命周期发生在onResume()到onPause()之间,这时Activity在手机屏幕的最前端,所以这两个方法中的代码应尽量轻量级,一些复杂、耗时的代码尽量不要在这两个方法中,以防止用户长时间的等待。Activity完整的生命周期以及状态间的转换如下图所示:
图3 Activity生命周期
下面以一个简单的实例来研究Activity的生命周期,首先创建一个Activity,效果如下:
图4 应用效果
其中有两个按钮,一个按钮弹出一个对话框,一个按钮打开一个新的Activity,这两个Activity在AndroidManifest.xml中定义如下:
- <!-- android:theme实现系统默认对话框效果 -->
- <activity android:name=".PauseActivity" android:theme="@android:style/Theme.Dialog" />
- <activity android:name=".StopActivity" />
MainActivity的实现代码如下:
- public class MainActivity extends Activity {
- private static String TAG = "MainActivity";
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Log.i(TAG, "执行onCreate()");
- }
- /**
- * 弹出对话框
- * @param v
- */
- public void openPauseActivity(View v){
- startActivity(new Intent(this, PauseActivity.class));
- }
- /**
- * 打开新的activity
- * @param v
- */
- public void openStopActivity(View v){
- startActivity(new Intent(this, StopActivity.class));
- }
- @Override
- protected void onStart() {
- Log.i(TAG, "执行onStart()");
- super.onStart();
- }
- @Override
- protected void onRestart() {
- Log.i(TAG, "执行onRestart()");
- super.onRestart();
- }
- @Override
- protected void onResume() {
- Log.i(TAG, "执行onResume()");
- super.onResume();
- }
- @Override
- protected void onStop() {
- Log.i(TAG, "执行onStop()");
- super.onStop();
- }
- @Override
- protected void onPause() {
- Log.i(TAG, "执行onPause()");
- super.onPause();
- }
- @Override
- protected void onDestroy() {
- Log.i(TAG, "执行onDestroy()");
- super.onDestroy();
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- }
测试1:打开应用进入主界面,运行效果如图4,后台打印日志如下:
图5 进入主界面时,执行的方法
在整个生命周期的位置如下:
图6 测试1在生命周期位置
测试2:点击"对话框"按钮,弹出对话框,运行效果如下:
图7 测试2弹出对话框
MainActivity运行的方法,紧接着图5,弹出对话框时,MainActivity只运行了一个onPause(),
图8 测试2后台打印日志
在整个生命周期的位置,如下:
图9 测试2在这个生命周期位置
测试3:点击返回,返回到MainActivity,这时后台打印日志如下图所示,相当于只执行了onResume()
图10 测试3后台日志
在这个生命周期的位置如下图所示
图11 测试3在生命周期位置图
测试4:点击新Activity按钮,打开新Activity,后台打印日志如下图所示
图12 测试4后台日志打印
在整个生命周期的位置,如下图所示。
图13 测试4生命周期位置图
测试5:点击返回、返回MainActivity,后台打印日志如下图所示
图14 测试5 后台日志打印图
在这个生命周期的位置如下图所示。
图15 生命周期图
测试6:点击键盘上home键,返回手机主屏幕,然后再打开应用,后台打印日志如下图所示。
图16 测试6日志打印
在整个生命周期的位置,如下图所示。
未完待续....
参考资料:
Google Android 的开发者网站:http://developer.android.com/
IBM DeveloperWorks中国文章(详解Android的Activity组件):http://www.ibm.com/developerworks/cn/opensource/os-cn-android-actvt/