Activity与Intent深入剖析

         本篇内容:

        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时通过如下方式指定:    

  
  
  
  
  1. <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生命周期内各种状态间的转换。

  
  
  
  
  1. public class MyActivity extends Activity {     
  2.     protected void onCreate(Bundle savedInstanceState);     
  3.     protected void onStart();     
  4.     protected void onResume();     
  5.     protected void onPause();     
  6.     protected void onStop();     
  7.     protected void onDestroy();     
  8.  } 

        一个完整的生命周期从调用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中定义如下:

  
  
  
  
  1. <!-- android:theme实现系统默认对话框效果 --> 
  2. <activity android:name=".PauseActivity" android:theme="@android:style/Theme.Dialog" />    
  3. <activity android:name=".StopActivity" /> 

        MainActivity的实现代码如下:

  
  
  
  
  1. public class MainActivity extends Activity {    
  2.                                                               
  3.     private static String TAG = "MainActivity";    
  4.                                                               
  5.     @Override 
  6.     public void onCreate(Bundle savedInstanceState) {    
  7.         super.onCreate(savedInstanceState);    
  8.         setContentView(R.layout.main);    
  9.         Log.i(TAG, "执行onCreate()");    
  10.     }    
  11.                                                               
  12.     /**    
  13.      * 弹出对话框    
  14.      * @param v    
  15.      */ 
  16.     public void openPauseActivity(View v){    
  17.         startActivity(new Intent(this, PauseActivity.class));    
  18.     }    
  19.                                                               
  20.     /**    
  21.      * 打开新的activity    
  22.      * @param v    
  23.      */ 
  24.     public void openStopActivity(View v){    
  25.         startActivity(new Intent(this, StopActivity.class));    
  26.     }    
  27.                                                           
  28.     @Override 
  29.     protected void onStart() {    
  30.         Log.i(TAG, "执行onStart()");    
  31.         super.onStart();    
  32.     }    
  33.                                                           
  34.     @Override 
  35.     protected void onRestart() {    
  36.         Log.i(TAG, "执行onRestart()");    
  37.         super.onRestart();    
  38.     }    
  39.                                                           
  40.     @Override 
  41.     protected void onResume() {    
  42.         Log.i(TAG, "执行onResume()");    
  43.         super.onResume();    
  44.     }    
  45.                                                           
  46.     @Override 
  47.     protected void onStop() {    
  48.         Log.i(TAG, "执行onStop()");    
  49.         super.onStop();    
  50.     }    
  51.                                                           
  52.     @Override 
  53.     protected void onPause() {    
  54.         Log.i(TAG, "执行onPause()");    
  55.         super.onPause();    
  56.     }    
  57.                                                           
  58.     @Override 
  59.     protected void onDestroy() {    
  60.         Log.i(TAG, "执行onDestroy()");    
  61.         super.onDestroy();    
  62.     }    
  63.                                                               
  64.     @Override 
  65.     public boolean onCreateOptionsMenu(Menu menu) {    
  66.         getMenuInflater().inflate(R.menu.main, menu);    
  67.         return true;    
  68.     }    

 

       测试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/

 

你可能感兴趣的:(android,Activity生命周期,Activity启动模式,activity栈)