Android的生命周期图

来源:互联网 发布:央视直播软件哪个好 编辑:程序博客网 时间:2024/06/06 23:55

 说Activity是Android的七巧板,是因为,如果把Android的所有界面比作一副用用七巧板拼成的图画的话,那么每个Activity都相当于一块七巧板。这个七巧板与他所在的package,所在的应用无关。任何应用都可以把自己的七巧板拿出来让别人组装成他们的图画,自己也可以拿别的应用的七巧板来组装自己的图画。

    现在开始我们的七巧板之旅!

    这个专题总结一下Activity的生命周期。

    好吧,先插一个document里的图片。这个图是免不了的。

    下面我们以实际例子来解释上图的Activity的生命周期。

    我们新建一个工程,并建两个Activity,Activity1和Activity2。我用的工具是Intellij Idea,(这里还是夸奖一下idea的人性化,在eclipse中建立Activity还需要在AndroidManifest.xml中手动注册一下,而是用idea,会发现,新建Activity后已经自动在AndroidManifest.xml中注册过了。)两个Activity的代码如下:

Java代码  收藏代码
  1. /**Activity1的代码*/   
  2. public class Activity1 extends Activity {    
  3.         private static final String TAG = "Activity1";    
  4.         @Override   
  5.         public void onCreate(Bundle savedInstanceState) {   
  6.            Log.i(TAG, "Activity1 onCreate called!");    
  7.            super.onCreate(savedInstanceState);    
  8.            setContentView(R.layout.main);    
  9.             }    
  10.         @Override   
  11.         protected void onStart() {    
  12.            Log.i(TAG, "Activity1 onStart called!");    
  13.            super.onStart();    
  14.         }        
  15.         @Override   
  16.         protected void onRestart() {    
  17.            Log.i(TAG, "Activity1 onRestart called!");    
  18.            super.onRestart();    
  19.         }    
  20.         @Override   
  21.         protected void onResume() {    
  22.           Log.i(TAG, "Activity1 onResume called!");    
  23.           super.onResume();    
  24.         }  
  25.         @Override  
  26.         protected void onPause() {    
  27.           Log.i(TAG, "Activity1 onPause called!");    
  28.           super.onPause();    
  29.         }       
  30.         @Override     
  31.         protected void onStop() {    
  32.            Log.i(TAG, "Activity1 onStop called!");    
  33.            super.onStop();    
  34.         }    
  35.         @Override   
  36.         protected void onDestroy() {    
  37.           Log.i(TAG, "Activity1 onDestroy called!");    
  38.           super.onDestroy();     
  39.         }    
  40.          /**当点击屏幕时,进入Activity2*/   
  41.          @Override   
  42.          public boolean onTouchEvent(MotionEvent event) {    
  43.             Intent intent = new Intent(this, Activity2.class);    
  44.             startActivity(intent);    
  45.             return super.onTouchEvent(event);    
  46.         }   
  47.  }   
  48.   
  49. /**Activity1的代码*/   
  50. public class Activity2 extends Activity {    
  51.         private static final String TAG = "Activity2";    
  52.         @Override   
  53.         public void onCreate(Bundle savedInstanceState) {   
  54.            Log.i(TAG, "Activity2 onCreate called!");  
  55.                 setContentView(R.layout.main2);     
  56.            super.onCreate(savedInstanceState);    
  57.              
  58.             }    
  59.         @Override   
  60.         protected void onStart() {    
  61.            Log.i(TAG, "Activity2 onStart called!");    
  62.            super.onStart();    
  63.         }        
  64.         @Override   
  65.         protected void onRestart() {    
  66.            Log.i(TAG, "Activity2 onRestart called!");    
  67.            super.onRestart();    
  68.         }    
  69.         @Override   
  70.         protected void onResume() {    
  71.           Log.i(TAG, "Activity2 onResume called!");    
  72.           super.onResume();    
  73.         }  
  74.         @Override  
  75.         protected void onPause() {    
  76.           Log.i(TAG, "Activity2 onPause called!");    
  77.           super.onPause();    
  78.         }       
  79.         @Override     
  80.         protected void onStop() {    
  81.            Log.i(TAG, "Activity2 onStop called!");    
  82.            super.onStop();    
  83.         }    
  84.         @Override   
  85.         protected void onDestroy() {    
  86.           Log.i(TAG, "Activity2 onDestroy called!");    
  87.           super.onDestroy();     
  88.         }    
  89.            
  90.  }   

 

然后我们在Activity1的layout文件中加入一个EditText

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
  3.               android:orientation="vertical"   
  4.               android:layout_width="fill_parent"   
  5.               android:layout_height="fill_parent"   
  6.         >   
  7.     <TextView  
  8.             android:layout_width="fill_parent"   
  9.             android:layout_height="wrap_content"   
  10.             android:text="Hello World, Activity1"   
  11.             />   
  12.        
  13. <EditText   
  14.             android:layout_width="fill_parent"   
  15.             android:layout_height="50sp"   
  16.             />   
  17. </LinearLayout>   

 

流程1

 我们启动程序,进入Activity1,在Activity1的文本框中输入一段文字,然后按返回键,然后看Logcat里的调试信息。

 

Java代码  收藏代码
  1. 02-27 13:38:27.067: INFO/Activity1(566): Activity1 onCreate called!  
  2.    02-27 13:38:27.157: INFO/Activity1(566): Activity1 onStart called!  
  3.    02-27 13:38:27.157: INFO/Activity1(566): Activity1 onResume called!  
  4.   
  5.    02-27 13:41:08.107: INFO/Activity1(566): Activity1 onPause called!  
  6.    02-27 13:41:08.897: INFO/Activity1(566): Activity1 onStop called!  
  7.    02-27 13:41:08.897: INFO/Activity1(566): Activity1 onDestroy called!  

 

     从Log信息我们可以看出,进入Activity,然后按返回键退出。Activity的生命周期经过里流程图上的竖直的路线。onCreate->onStart->onPause->onStop->onDestroy。这时的Activity寿终正寝。

    当我们再次进入Activity1时,我们会发现,Activity1中的文本框的内容又成了空了,因此可以推断,Activity1内的空间已经被销毁,又重新生成了。

流程2

    我们启动程序,进入Activity1,在Activity1内输入一段文本,点击Activity1,进入Activity2,然后Activity2中按返回键。或者采用这个流程,启动程序进入Activity1,按Home键进入桌面,然后长按Home建点击该应用重新进入Activity1.

    然后看Log信息。

Java代码  收藏代码
  1. 02-27 13:55:35.727: INFO/Activity1(600): Activity1 onCreate called!  
  2.     02-27 13:55:35.837: INFO/Activity1(600): Activity1 onStart called!  
  3.     02-27 13:55:35.837: INFO/Activity1(600): Activity1 onResume called!  
  4.   
  5.     02-27 13:55:40.287: INFO/Activity1(600): Activity1 onPause called!  
  6.   
  7.     02-27 13:55:41.227: INFO/Activity1(600): Activity1 onStop called!  
  8.   
  9.     02-27 14:06:43.017: INFO/Activity1(634): Activity1 onRestart called!  
  10.     02-27 14:06:43.017: INFO/Activity1(634): Activity1 onStart called!  
  11.     02-27 14:06:43.017: INFO/Activity1(634): Activity1 onResume called!  

 

    从这个log信息,我们看出,当从Activity1进入Activity2时,Activity1经历的过程为onCreate->onStart->onResume->onPause->onStop->onRestart->onStart->onResume。这个过程说明了图中,如果Activity完全被其他界面遮挡时,进入后台,并没有完全销毁,当再次进入该Activity时,onRestart->onStart->onResume,又重新恢复。这说明充分说明了,斩草不除根,死灰也会复燃。。。有点邪恶啊。

    我们发现,从Activity2返回到Activity1时,Activity1内的文本并没有发生变化,因此可以推断,当Activity onStop后其内的成员状态并没有改变。

    是不是被所有的界面全部遮挡都会进入onStop呢?我们看下面一个流程。

流程3

    启动程序,进入Activity1,然后按挂机键,进入锁屏界面,然后从锁屏界面返回Activity1。我们查看log信息。

Java代码  收藏代码
  1. 02-27 14:17:45.257: INFO/Activity1(810): Activity1 onCreate called!  
  2.  02-27 14:17:45.347: INFO/Activity1(810): Activity1 onStart called!  
  3.  02-27 14:17:45.347: INFO/Activity1(810): Activity1 onResume called!  
  4.   
  5.   02-27 14:17:51.177: INFO/Activity1(810): Activity1 onPause called!  
  6.   
  7.  02-27 14:18:04.757: INFO/Activity1(810): Activity1 onResume called!  

 

     从log信息可以看出,Activity1被锁屏界面全部遮挡后并没有进入onStop,而仅仅进入onPause后就停止了,当从锁屏界面返回Activity1时,调用了onResume。

    锁屏界面为什么会特殊呢,因为我们知道,进入onPause后,Activity始终还是活动的,再次onResume是不需要什么花费的,可以频繁的onPause,onResume;而onStop,onStart就会有比较多的花费。为了保障锁屏返回后,原先顶部的Acitivtiy能够快速的返回到原来的状态,显然锁屏界面进行了特殊的处理。

    同样,EditText的文本也没有发生变化,因此onPause也没有改变Activity内成员的状态。

Xml代码  收藏代码
  1. <activity android:name=".Activity2"   
  2.           android:label="Activity2"   
  3.          android:theme="@android:style/Theme.Dialog"/>   

 

这样Activity2在运行时就会以对话框的样式来运行了。

    所以我们首先点击程序进入Activity1,在EditText中输入一段文本,点击Activity1进入Activity2,然后按返回键返回Activity1。

 我们看log信息为:

Java代码  收藏代码
  1. 02-27 15:13:56.467: INFO/Activity1(962): Activity1 onCreate called!  
  2. 02-27 15:13:56.567: INFO/Activity1(962): Activity1 onStart called!  
  3. 02-27 15:13:56.567: INFO/Activity1(962): Activity1 onResume called!  
  4.   
  5. 02-27 15:14:09.197: INFO/Activity1(962): Activity1 onPause called!  
  6.   
  7. 02-27 15:20:50.607: INFO/Activity1(962): Activity1 onResume called!  

 从log信息我们可以看出,当Activity被部分遮挡时,Activity进入onPause,并没有进入onStop,从Activity2返回后,执行了onResume,而且和我们想的一样,EditText的文本没有发生变化。

 流程5

    将Activity1的onTouchEvent函数进行修改,如下:

Java代码  收藏代码
  1. @Override   
  2. public boolean onTouchEvent(MotionEvent event) {   
  3.     //启动一个AlertDialog       
  4.     new AlertDialog.Builder(this).setTitle("hello dialog!").show();   
  5.        
  6.    return super.onTouchEvent(event); 7.}   

 

打开程序,启动Activity1,点击Activity1,启动AlertDialog,按返回键从AlertDialog返回。

观察Log信息如下:

Java代码  收藏代码
  1. 02-28 10:03:28.535: INFO/Activity1(1234): Activity1 onCreate called!  
  2.   
  3. 02-28 10:03:28.605: INFO/Activity1(1234): Activity1 onStart called!  
  4.   
  5. 02-28 10:03:28.615: INFO/Activity1(1234): Activity1 onResume called!  

 

 从Log信息可以看出,当启动和退出Dialog时,Activity的状态始终未变,可见,Dialog实际上属于Acitivity内部的界面,不会影响Acitivty的生命周期。

 流程6

启动程序,进入Activity1,然后按返回键,主界面。我们查看log信息。

Java代码  收藏代码
  1. 02-27 14:17:45.257: INFO/Activity1(810): Activity1 onCreate called!  
  2.  02-27 14:17:45.347: INFO/Activity1(810): Activity1 onStart called!  
  3.  02-27 14:17:45.347: INFO/Activity1(810): Activity1 onResume called!  
  4.   
  5. 02-27 14:17:51.177: INFO/Activity1(810): Activity1 onPause called!  
  6. 02-27 14:17:51.177: INFO/Activity1(810): Activity1 onStop called!  
  7. 02-27 14:17:51.177: INFO/Activity1(810): Activity1 onDestroy called!  

 

  特殊情况

     从流程图上我们可以看出,无论现在是onPause状态还是onStop状态,当系统的内存不足时,都会将该Activity杀死,当再次进入该Activity重新创建。

    这意味着,如果发生这种情况,可能我们的onDestroy,甚至是onStop都没有得到执行,因此,一些重要的数据和状态,需要在这种情况下也得到保存,Google为我们专门提供了一个回调函数,就是onSaveInstanceState(Bundle),通过该函数,可以将这些重要的数据在销毁前进行保存,然后再onCreate时重新读出。

原创粉丝点击