Activity的生命周期
一.概述
在Android系统中,一个Activity自从被创建到消亡有六种形态,这些形态之间的互相转换会调用相应的方法来处理。它们之间的关系可以用下面的这张图来说明,这张图来自于Android Developer的相关说明http://developer.android.com/training/basics/activity-lifecycle/starting.html:
从这张图中,我们可以比较清楚的看出,Activity的生命周期有下面几种:
(1)Created:一个Activist对象被创建。
(2)Started:一个Activity对象开始执行。
(3)Resumed:Activity处于前台可见状态,在此状态下,用户可以与之进行交互(interact),也不妨称为“Running State”。
(4)Paused:Activity被另一个Activity(如对话框)部分挡住而无法与用户交互,也无法执行任何代码。
(5)Stopped:Activity被另一个Activity完全遮住而使得用户不可见,这时Activity在后台运行,数据仍然保存,但是不能执行任何操作。
(6)Destroyed:Activity被销毁。
其中,在这六种状态中,中间三种是可以较长时间存在的,其余三中只是一个很短暂的过程,系统将会很快转换到其他状态当中,不妨叫它们”过渡过程“吧。举例来说,当一个Activity调用OnCreate方法被创建后,它会接着调用OnStart方法转到Started状态,又会调用OnResume方法转到Resumed状态。在下文中我们将用代码和DDMS来说明这一点。
二.状态转换时的回调方法
由上面的图中我们就可以看到,当Activity的状态发生转换时,要调用相应的回调方法(CallBack Methods)。它们都是我们的自定义Activity继承自Activity的成员方法。
(1)onCreate()方法
当Activity第一次被创建的时候调用,在这里面我们一般进行Activity的初始化,比如通过setContentView()方法初始化控件的布局,为一些控件类实例化对象,绑定数据等。这个方法的原型为:protected void onCreate(Bundle savedInstanceState),可以看到它有一个Bundle类型的参数,这个参数包含了一些和Activity之前状态有关的数据。
onStart()方法常常在其后被调用。
(2)onRestart()方法
当Activity已经被停止后又被重新启动的时候被调用。
onStart()方法常常在其后被调用。
(3)onStart()方法
当Activity进入可见状态之前被调用。
如果Activity进入了前台,那么会接着调用onResume()方法;
如果Activity被遮挡住了,那么会接着调用onStop()方法。
(4)onResume()方法
当Activity处于与用户可以进行交互状态之前被调用。
(5)onPause()方法
当另一个Activity被唤起时被调用。
在这个方法里面,通常进行数据的存储操作,防止数据丢失。如果当前Activity占用了大量的系统资源,也要进行资源的释放,减轻CPU的压力。
同时也要注意,这个方法的效率一定要高,否则下一个将要启动的Activity将会等待这个方法返回,从而影响用户体验。
如果该Activity重新被唤起,则会接着调用onResum()方法;
如果该Activity变得不可见,则会接着调用onStop()方法。
(6)onStop()方法
当Activity变得不可见的时候被调用。这可以分为下面两种情况:
当Activity是被销毁时,会接着调用onDestroy()方法;
当Activity是被其他的Activity挡住而变得不可见的时候,当Activity被重新唤起会调用onRestart()方法。
(7)onDestroy()方法
当Activity被销毁或是系统处于对内存空间等的调度而暂时杀死这个Activity时被调用。
这两种情况可以通过isFinishing()方法来判断。
三.举例
在下面的代码中,我们建立了三个Activity。其中Main_Activity是启动应用后的Activity。在这个Activity中有两个按钮,分别可以进入SecondActivity和ThirdActivity中。其中SecondActivity是一个全屏的Activity,它会完全遮挡我们的Main_Activity;而ThirdActivity是一个对话框形式的Activity,会部分遮挡我们的Main_Activity。
下面贴出代码:
首先是Main_Activity的布局文件activity_main.xml的代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <!-- 显示控件 --> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/fisrtActivityName" /> <!-- 进入SecondActivity 的按钮--> <Button android:id="@+id/firstbutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/textView" android:layout_centerHorizontal="true" android:layout_marginTop="30dp" android:text="@string/enterSecondActivity" /> <!-- 进入ThirdActivity的按钮 --> <Button android:id="@+id/secondbutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/firstbutton" android:layout_below="@id/firstbutton" android:layout_marginTop="26dp" android:text="@string/enterThirdActivity" /> </RelativeLayout>
然后是Main_Activity的实现代码,在这里,我们将复写父类Activity上面提到的一系列方法,并为两个按钮添加onClickListener的监听事件。
package com.xmfbit.s01_lifeofactivity ; import android.os.Bundle ; import android.app.Activity ; import android.content.Intent ; import android.view.Menu ; import android.view.View ; import android.widget.Button ; public class MainActivity extends Activity { //第一个按钮,进入SecondActivity Button fbutton=null; //第二个按钮,进入ThirdActivity Button sbutton=null; @ Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState) ; setContentView(R.layout.activity_main) ; System.out.println("调用了onCreate方法!"); /* * 进入SecondActivity,本Activity被完全遮挡 */ fbutton=(Button)findViewById(R.id.firstbutton); fbutton.setOnClickListener(new View.OnClickListener() { @ Override public void onClick(View v) { // TODO Auto-generated method stub Intent it=new Intent(); it.setClass(MainActivity.this, SecondActivity.class); //进入SecondActivity startActivity(it); } }); /* * 跳转到ThirdActivity,是一个对话框,Activity将被部分遮挡 */ sbutton=(Button)findViewById(R.id.secondbutton); sbutton.setOnClickListener(new View.OnClickListener() { @ Override public void onClick(View v) { // TODO Auto-generated method stub Intent it=new Intent(); it.setClass(MainActivity.this, ThirdActicity.class); //进入ThirdActivity startActivity(it); } }); } @ Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu) ; return true ; } @ Override protected void onDestroy() { System.out.println("调用了onDestroy方法!"); // TODO Auto-generated method stub super.onDestroy() ; } @ Override protected void onPause() { System.out.println("调用了onPause方法!"); // TODO Auto-generated method stub super.onPause() ; } @ Override protected void onRestart() { System.out.println("调用了onRestart方法!"); // TODO Auto-generated method stub super.onRestart() ; } @ Override protected void onResume() { // TODO Auto-generated method stub System.out.println("调用了onResume方法!"); super.onResume() ; } @ Override protected void onStart() { System.out.println("调用了onStart方法!"); // TODO Auto-generated method stub super.onStart() ; } @ Override protected void onStop() { System.out.println("调用了onStop方法!"); // TODO Auto-generated method stub super.onStop() ; } }
如此,我们通过Intent的使用,就可以在Main_Activity中启动另外的Activity。
SecondActivity和ThirdActivity并没有进行多少改动,在建立class的时候选择继承自Activity,Eclipse就会给出模板,直接拿来用就行了。
接下来,我们必须要在Mainfest文件中声明SecondActivity和ThirdActivity,同时将ThirdActivity声明为一个对话框,这可以通过设置它的android:theme属性来实现。Mainfest.xml文件代码如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xmfbit.s01_lifeofactivity" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.xmfbit.s01_lifeofactivity.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.xmfbit.s01_lifeofactivity.SecondActivity" android:label="@string/app_name"> </activity> <activity android:name="com.xmfbit.s01_lifeofactivity.ThirdActicity" android:label="@string/app_name" android:theme="@android:style/Theme.Dialog"> </activity> </application> </manifest>
接下来,我们利用DDMS来查看当我们启动另两个Activity的时候,系统的输出。
启动模拟器,并在Logcat中添加System.out监视,应用运行效果如图:
(1)启动应用后,可以看到System.out输出了下面的信息:
可以看到,在这一启动过程中,依次执行了onCreate,onStart,onResume方法。
(2)我们先点击按钮1进入SecondActivity,
SecondActivity挡住了Main_Activity,使其变得不可见,所以调用了onPause和onStop方法。
(3)按下返回键,返回Main_Activity,
再次返回Main_Activity,调用onRestart,onStart和onResume方法。
(4)按下第二个按钮进入ThirdActivity。
输出信息:
和进入SecondActivity对比,可以看到这次只执行了onPause方法,而没有执行onStop方法,这是由于ThirdActivity是一个对话框并没有完全遮挡MainActivity,使其完全不可见的原因。
(5)按下屏幕空白位置返回
可以看到,由于MainActivity再次变成可见,所以调用了onResume方法。由于MainActivity没有被Stop,所以没有调用onRestart和onStart方法。
写了好长时间,才发现其实没有总结很多东西。上面这些在android的参考网站上都可以查到。上面只是用了一个很简单的例子来说明在状态转换的过程中与之相关的方法的调用,至于每个方法的具体实际应用,还是应该在实际中运用才可以。