Android Activity生命周期
每启动Android一个应用时,便开始执行Activity生命周期。Android Activity生命周期指从开始onCreate()到销毁onDestory()整个过程。
Android生命周期基本可以归结为四个过程:
1.
活动状态:onCreate()=>onStart()=>onResume()
2.
暂停状态:活动状态=>onPause()
3.
停止状态:暂停状态=>onStop()
4.
销毁状态:销毁状态=>onDestroy()
其中在Activity中的主要流程及其回调过程由以下组成
图1.android
Activity生命周期及其回调过程
从图1中可看出在一个Activity starts到Activity is shut down的过程中共包含7个方法,1条主线,4条循环分支。
七个方法功能:
onCreate():
当一个Activity启动后首先调用到的过程。该方法未被Destroy或kill时该方法只被调用一次。
onStart():
启动Activity时一定会回调该方法。当Activity启动后,执行到onStop()停止后,重新调用该Activity时也回调该方法。
OnResume():
启动Activity时一定会回调该方法。当Activity启动后,执行到onPause()暂停后,重新调用该Activity时回调该方法。执行完该方法后,Activity处于活动状态。
从Log中可看出,在启动过程中按OnCtreat=>onStart=>onResume三个过程进行。到了OnResume方法后便开始第一个状态:活动状态
OnPause():
当前Activity部分Layout被另一Activity覆盖时,当前Activity执行该方法。当另一Activity执行结束后退出,将回调当前Activity中的OnResume()方法
从Log中可以看出当前Activity部分被覆盖后,调用OnPause,并启动了另一Activity(ThirdActivity)。关闭ThirdActivity后重新回调了MainActivity中的OnResume方法。而该方法是在ThirdActivty状态处于OnPause后OnStop前回调该方法。该过程为暂停活动状态。
OnStop():
当前Activity未退出但启动另一Activity并覆盖当前Activity时调用OnStop该方法。
从log中可看出启动SecondActivity后先调用MainActivity中的OnPause方法后,SecondActivity将处于活动状态。当SecondActivity处于活动状态后,才执行MainActivity中OnStop方法,将MainActivity置于停止状态。
OnRestart():
当另一Activity结束后,重新回到当前Activity将调用OnRestart方法后调用再onStart方法,执行正常的活动状态
从log中可看出当SecondActivity退出时,先执行OnPause后才执行MainActivity中的OnRestart,当MainActivity处于活动状态后,SecondActivity才开始停止并销毁自身的Activity。
OnDestory()
一个Activity结束后,最终会执行OnDestory方法,将该Activity进行销毁。但存在一种特殊情况,就是当其他applications需要更多内存时,当前Activity可能会被Kill,若当前Activity被kill后,将不调用OnDestory。
一条主线:
从一个Activity建立开始到一个Activity结束,中间无调用其他Activity:
OnCreate=>onStart=>onResume=>onPause=>onStop=>onDestory
若此时存在一控件TextView,且该控件赋予一定的值时,例如:
此时在该Application未退出,只执行到OnDestroy(即:被其他Activity覆盖),重新调用该Activity,虽然界面上的EditText依然显示test,但在OnCreate和OnStart中该值暂时为空,直到OnResume回调后,才能获取到EditText上的值。
四条循环:
1.
当前Activity部分被遮盖时:
当前Activity处于OnPause,并被重新处于栈顶时,该过程先执行OnPause后,执行OnResume
当调用OnPause后,重新回调OnResume,此时EditText中的值,依然存在,且不被销毁,也不必重新赋值。
2.
当前Activity被其他Activity覆盖时:
当前Activity处于OnStop状态,当被重新处于栈顶时,该过程为
OnStop=>onRestart=>onStart=>……
调用OnStop后,该EditText的在OnRestart中依然存在,不被销毁,也不需要重新进行赋值操作。
3.
处于OnPause时,其他Application需要更多内存空间时:
此时会将当前Activity
Kill掉并没执行OnDestory该方法。
当重新将该Activity处于栈顶时,将重新Create:
OnPause=>onCreate=>……
在Activity被kill掉之后,但Android会默认保存Activity中的UI部分信息,所以当Activity重新启动后,EditText中的值依然存在。
但在更多地情况下,当Activity被Kill掉后,里面的值便随之被销毁。此时可以通过onSaveInstanceState(Bundle
savedInstanceState)来对值进行保存。该方法与onPause后调用。
当信息被保存后,若Activity被kill或OnDestroy后,可以通过onRestoreInstanceState(Bundle
savedInstanceState)或在onCreate(Bundle
savedInstanceState)中的savedInstanceState取得到保存的值:
if(savedInstanceState !=
null){
String testValue = savedInstanceState.getString("testValue");
}
而onRestoreInstanceState在OnStart后调用。
onSaveInstanceState该方法比较适合存放简单的数据,对于数据量较大的信息不推荐使用。信息量较大的信息应该做好数据库保存或文件保存等方式。
4.
处于OnStop,其他Application需要更掉内存空间时:
状态同4
MainActivity执行的部分代码
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private EditText etValue;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate");
etValue = (EditText)
findViewById(R.id.et_test_value);
if(savedInstanceState !=
null){
String testValue = savedInstanceState.getString("testValue");
etValue.setText(testValue);
}
findViewById(R.id.btn_start_second_activity).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(intent);
}
});
findViewById(R.id.btn_change_screen_orientation).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int orientation =
getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE?
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
setRequestedOrientation(orientation);
}
});
findViewById(R.id.btn_start_dialog).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new Builder(MainActivity.this);
dialog.setTitle("title");
dialog.setMessage("shut out main
activity");
dialog.setPositiveButton("stop", newAlertDialog.OnClickListener()
{
@Override
public voidonClick(DialogInterface
dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
});
findViewById(R.id.btn_start_third_activity).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
ThirdActivity.class);
startActivity(intent);
}
});
Log.d(TAG,"editText value is "
+ etValue.getText().toString());
}
@Override
protected void onStart() {
Log.d(TAG,"onStart");
Log.d(TAG,"editText value is "
+ etValue.getText().toString());
super.onStart();
}
@Override
protected void onResume() {
Log.d(TAG,"onResume");
Log.d(TAG,"editText value is "
+ etValue.getText().toString());
super.onResume();
}
@Override
protected void onPause() {
Log.d(TAG,"onPause");
Log.d(TAG,"editText value is "
+ etValue.getText().toString());
super.onPause();
}
@Override
protected void onStop() {
Log.d(TAG,"onStop");
Log.d(TAG,"editText value is "
+ etValue.getText().toString());
super.onStop();
}
@Override
protected void onRestart() {
Log.d(TAG,"onRestart");
Log.d(TAG,"editText value is "
+ etValue.getText().toString());
super.onRestart();
}
@Override
protected void onDestroy() {
Log.d(TAG,"onDestroy");
Log.d(TAG,"editText value is "
+ etValue.getText().toString());
super.onDestroy();
}
@Override
protected voidonSaveInstanceState(Bundle
savedInstanceState) {
Log.d(TAG,"onSaveInstanceState");
savedInstanceState.putString("testValue", etValue.getText().toString());
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected voidonRestoreInstanceState(Bundle
savedInstanceState) {
String testValue = savedInstanceState.getString("testValue");
Log.d(TAG,"onRestoreInstanceState lost value is
:"+testValue);
super.onRestoreInstanceState(savedInstanceState);
}