每个活动在其生命周期中无非有以下几个状态:
1. 运行状态
当一个活动位于返回栈的栈顶时,这时的活动就处于运行状态,这时活动是可见的。
2. 暂停状态
当一个活动不再处于栈顶位置但是依然可见的情况下,它就处于暂停状态。(有可能是当前活动之上有个不能覆盖全部屏幕的对话框出现)
3. 停止状态
当一个活动不再处于栈顶位置并且完全不可见时就处于停止状态。系统仍然会为这种活动保存相应的状态和成员变量,但是不是百分百的,当系统内存开销较大时,处于停止状态的活动可能会被系统回收。
4. 销毁状态
当一个活动从返回栈中被移除后就变成了销毁状态,系统会优先回收处于销毁状态的活动以保证足够内存。
活动的生命周期:
1. onCreate()
它会在活动第一次被创建的时候调用此方法。此方法中应该做活动初始化相关的操作,比如:加载布局、声明控件、绑定事件等。
2. onStart()
它会在活动从不可见变为可见时被调用。此时活动处于返回栈顶并处于运行状态。比较适合做页面刷新等操作。
3. onResume()
这个方法在活动准备好和用户进行交互时被调用。此时该活动一定处于返回栈顶且处于运行状态。
4. onPause()
这个方法是系统准备去启动或者恢复另一个活动时被调用。通常在此方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据。
5. onStop()
这个方法在活动完全不可见的情况才会被调用。它和onPause()方法的区别在于。当弹出对话框时,当前活动还可见,就会执行onResume()而不执行onStop()。
6. onDestroy()
这个方法在活动被销毁之前调用,之后活动变为销毁状态。
7. onRestart()
这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重启了。
以上方法除了onRestart()方法其它都是两两相对的,我们可以把生命周期再分为三种生存期。
1. 完整生存期
活动在onCreate()方法和onDestroy()方法之间所经历的,就是完整生存期。一般情况下,一个活动会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。
2. 可见生存期
活动在onStart()方法和onStop()方法之间所经历的,就是可见生存期。在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两个方法,合理地管理那些对用户可见的资源。比如在onStart()方法中对资源进行加载,而在
onStop()方法中对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。
3. 前台生存期
活动在onResume()方法和onPause()方法之间所经历的,就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行相互的,我们平时看到和接触最多的也这个状态下的活动。
安卓官方示意图
下面来举个例子
有三个Activity对应三个layout
MainActivity.java--main_layout.xml
TestActivity01.java--test_layout01.xml
TestActivity02.java--test_layout02.xml
MainActivity.java
package com.example.mytest;
import com.example.mytest.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity{
public static final String TAG = "MainActivity";
Button button1,button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.main_layout);
button1 = (Button) findViewById(R.id.xml_button1);
button2 = (Button) findViewById(R.id.xml_button2);
button1.setOnClickListener(new MyListener());
button2.setOnClickListener(new MyListener());
}
class MyListener implements OnClickListener{
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.xml_button1:
startActivity(new Intent(MainActivity.this, TestActivity01.class));
break;
case R.id.xml_button2:
startActivity(new Intent(MainActivity.this, TestActivity02.class));
break;
default:
break;
}
}
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart");
}
}
TestActivity01 .java
package com.example.mytest;
import com.example.mytest.R;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity01 extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout01);
}
}
TestActivity02 .java
package com.example.mytest;
import com.example.mytest.R;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity02 extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout02);
}
}
因为太过简单,对应的xml布局文件就不贴出来了,把AndroidManifest.xml文件贴出来,可以看出来'TestActivity02'是对话框。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mytest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity">
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".TestActivity01"></activity>
<activity
android:name=".TestActivity02"
android:theme="@android:style/Theme.Dialog">
</activity>
</application>
</manifest>
理解过程:
1. 第一次运行APP
2.点击'start NormalActivity'
3. 点击back键返回MainActivity
4. 点击'start DialogActivity'
可以看到,只有onPause()方法得到了执行,onStop()方法并没有执行,这是因为DialogActivity并没有完全遮挡住MainActivity,此时MainActivity只是进入了暂停状态,并没有进入停止状态。
5. 点击back键返回
相应地,按下Back键返回MainActivity也应该只有onResume()方法会得到执行
6. 点击back键退出程序
有一种可能性,我们从活动A中跳转到B,在B中进行相应的操作后希望back回到A继续工作,但是当我们在B时,A是停止状态,那么系统就有可能因为内存不足把A释放掉,那么当我们返回A时APP会出错么?答案是不会出错,但是这时候A不会执行onrestart()函数,而是执行了onCreate()函数,可想而知,系统又重新创建了一个活动A,那么我们之前在A中的一些数据自然就不见了,该怎么办?别担心,Activity中提供了一个名为onSaveInstanceState()方法来避免被系统释放掉的活动引起的数据丢失。onSaveInstanceState()函数会保证在活动销毁之前调用。具体用法。
package com.example.mytest;
import com.example.mytest.R;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity01 extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout01);
if(savedInstanceState!=null){
String tempData = savedInstanceState.getString("myData");
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String str = "the activity will be destroy! let's save this";
outState.putString("myData", str);
}
}