Android程序创建时,系统会自动在其.java源文件中重写Activity类的onCreate方法,该方法是创建Activity时必须调用的一个方法,另外,Activity类中还提供了诸如onStart、onResume、onPause、onStop和onDestroy等方法,这些方法的先后执行顺序构成了Activity对象的一个完整生命周期。
在通常情况下并不需要都去实现Activity生命周期的所有方法,但Activity在运行时候发生一些突发事件的时候,比如要给电话突然打过来,要处理这些突发事件的,就需要使用到Activity的生命周期方法了。
Activity可分为三种状态:
激活状态也就是Resumed,当前Activity在屏幕前台也就是当前任务堆栈的顶部,它是处于激活状态,可接受用户事件进行响应
暂停状态即Paused 被另一Activity覆盖,但是没有完全覆盖或者说是透明的,这个时候用户可以看到之前的Activity
最后一个状态就是停止状态 Stopped,对于这个状态来说,用户是看不见的,完全隐藏的,但是用户的一些状态信息会依然保留,并不会执行。当系统内存不足时,就会杀死这个Activity,以获得更多的内存。
从图中可以看出Activity生命周期很像一座金字塔,可以清楚的看到三条生命周期线路:
1.onCreate--->onStart()--->OnResume()--->onPause()--->onStop()--->onDestroy()
2.onPause()--->onResume()
3.onRestart()--->onStart()--->onResume()
所有Activity状态的变化都是根据这三条线路先具体执行的。
当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
void onCreate(BundlesavedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void
onDestroy
()
根据上面的三个回路写个demo
package com.zjhcsoft.activitylifecycle;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private static final String TAG = "Main";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "OnCreate....................");
Button first = (Button)findViewById(R.id.first);
first.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,FirstActivity.class);
startActivity(intent);
}
});
Button second = (Button)findViewById(R.id.second);
second.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
@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;
}
/*(non Javadoc)
*<p>Title: onStart</p>
*<p>Description: </p>
*@see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart....................");
}
/*(non Javadoc)
*<p>Title: onRestart</p>
*<p>Description: </p>
*@see android.app.Activity#onRestart()
*/
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart....................");
}
/*(non Javadoc)
*<p>Title: onResume</p>
*<p>Description: </p>
*@see android.app.Activity#onResume()
*/
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume....................");
}
/*(non Javadoc)
*<p>Title: onPause</p>
*<p>Description: </p>
*@see android.app.Activity#onPause()
*/
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause....................");
}
/*(non Javadoc)
*<p>Title: onStop</p>
*<p>Description: </p>
*@see android.app.Activity#onStop()
*/
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop....................");
}
/*(non Javadoc)
*<p>Title: onDestroy</p>
*<p>Description: </p>
*@see android.app.Activity#onDestroy()
*/
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy....................");
}
}
生命周期执行回路:
onCreate-->onStart()--->onResume()
程序执行效果:
但按返回按钮时会执行:
onPause()--->onStop()--->onDestory()方法
假如当前Activity被其他Activity不完全覆盖情况下,执行生命周期回路:
onPause--->onResume()
在这种情况下,用户还能见到之前的Activity,只是不能操作之前的
程序执行效果图:
点击FirstActivity按钮
出现一个覆盖效果,当前Acitvity只执行onPause()方法,然后按返回键:
效果如下:
执行了onResume()方法
在这里要实现覆盖效果只需AndroidManifest.xml在配置android:theme="@android:style/Theme.Dialog"
代码如下:
<activity
android:name=".FirstActivity"
android:theme="@android:style/Theme.Dialog"
></activity>
在当前界面上点击Second Activity 按钮后按返回键会执行下面生命周期回路:
onRestart()--->onStart()--->onResume()
点击Second Activity 按钮后当前Activity进入停止状态,用户不可见,程序执行效果如下
当继续按返回键,返回时程序执行效果如下:
在这里提两个Activity方法:
1.onSaveInstanceState()
2.onRestoreInstanceState()
这两个方法并不是Activity生命周期方法,并不一定会触发,由系统销毁一个Activity时,onSaveInstanceState() 会被调用,另外Activity由运行状态进入暂停状态或停止状态也会调用该方法。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。
增加如下方法:
/*(non Javadoc)
*<p>Title: onRestoreInstanceState</p>
*<p>Description: </p>
*@param savedInstanceState
*@see android.app.Activity#onRestoreInstanceState(android.os.Bundle)
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState....................");
super.onRestoreInstanceState(savedInstanceState);
}
/*(non Javadoc)
*<p>Title: onSaveInstanceState</p>
*<p>Description: </p>
*@param outState
*@see android.app.Activity#onSaveInstanceState(android.os.Bundle)
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG, "onSaveInstanceState....................");
}
另外,当屏幕的方向发生了改变,Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activity的onSaveInstanceState()和onRestoreInstanceState()方法
当屏幕切换时候程序执行效果如下:
假如不想在屏幕切换时销毁当前Acitvity
那么就需要在AndroidManifest.xml配置文件中的Activity标签下面添加:android:configChanges="orientation|keyboardHidden"
然后在activity中重写onConfigurationChanged()方法,每次旋转时会调用该方法,可以再该方法中处理数据
程序执行效果如下:
所以当屏幕进行切换时什么时候保存数据保存什么数据就一目了然了。
代码地址: