Activity的生命周期分析





一:正常情况下Activity的生命周期:


代码举例: NormalActivity.java
public class NormalActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_normal);
Log.d("NormalActivity", "----onCreate----") ;
Button btn = (Button)findViewById(R.id.start_nb_id) ;
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it = new Intent() ;
it.setClass(NormalActivity.this,NormalActivityB.class) ;
startActivity(it);
}
});
}

@Override
protected void onStart() {
super.onStart();
Log.d("NormalActivity", "----onStart----") ;
}

@Override
protected void onRestart() {
super.onRestart();
Log.d("NormalActivity", "----onRestart----") ;
}

@Override
protected void onResume() {
super.onResume();
Log.d("NormalActivity", "----onResume----") ;
}

@Override
protected void onPause() {
super.onPause();
Log.d("NormalActivity", "----onPause----") ;
}

@Override
protected void onStop() {
super.onStop();
Log.d("NormalActivity", "----onStop----") ;
}

@Override
protected void onDestroy() {
super.onDestroy();
Log.d("NormalActivity", "----onDestroy----") ;
}
}
调试日志:

在MainActivity中启动NormalActivity  
01-18 16:27:11.312: D/NormalActivity: ----onCreate----
01-18 16:27:11.312: D/NormalActivity: ----onStart----
01-18 16:27:11.313: D/NormalActivity: ----onResume----


在NormalActivity中点击Button 启动NormalActivityB
01-18 16:22:44.438: D/NormalActivity: ----onPause----              (NormalActivity要先onPause())
01-18 16:22:44.489: D/NormalActivityB: ----onCreate----
01-18 16:22:44.489: D/NormalActivityB: ----onStart----
01-18 16:22:44.489: D/NormalActivityB: ----onResume----
01-18 16:22:44.851: D/NormalActivity: ----onStop----                (这时NormalActivity才onStop())


在NormalActivityB中按back键返回NormalActivity
01-18 16:23:17.693: D/NormalActivityB: ---- onPause----
01-18 16:23:17.706: D/NormalActivity: ----onRestart----
01-18 16:23:17.706: D/NormalActivity: ----onStart----
01-18 16:23:17.706: D/NormalActivity: ----onResume----
01-18 16:23:18.055: D/NormalActivityB: ---- onStop----
01-18 16:23:18.056: D/NormalActivityB: ----onDestroy----


在NormalActivity中按back键返回MainActivity
01-18 16:24:35.813: D/NormalActivity: ----onPause----
01-18 16:24:36.162: D/NormalActivity: ----onStop----
01-18 16:24:36.162: D/NormalActivity: ----onDestroy----


注意1:当新的Activity使用了透明主题,那么不会回调当前Activity的onStop(),只会调用其onPause()


注意:弹出Toast和AlertDialog都不会触发Activity的onPause():
public class NormalActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_normal);
Log.d("NormalActivity", "----onCreate----") ;

//弹出Toast提示 (调试结果表明不会触发onPause())
Button tipBtn = (Button)findViewById(R.id.tip_id) ;
tipBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(NormalActivity.this,"测试是否触发onSaveInstanceState方法",Toast.LENGTH_SHORT).show();
}
});

//弹出对话框 (调试结果表明不会触发onPause())
Button dialogBtn = (Button)findViewById(R.id.popup_dialog_id) ;
dialogBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(NormalActivity.this) ;
dialog.setTitle("对话框").setMessage("测试是否触发onSaveInstanceState方法") ;
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

}
}) ;
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

}
});
//创建和显示对话框
dialog.create().show();
}
});
}
}


二:异常情况下Activity的生命周期
  1,系统配置变化导致Activity被杀死并重新创建
            (如横竖屏切换,使用外接键盘,.......)
        
代码案例:ConfigChangeActivity.java
/**
* 分析异常情况下Activity的生命周期:
* 系统配置改变导致Activity被杀死并重新创建
*/
public class ConfigChangeActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_config_change);
if(savedInstanceState != null){
String data = savedInstanceState.getString("extra_data","--empty--") ;
Log.d("ConfigChangeActivity", "----onCreate[restore]---- extra_data:" +data) ;
}else{
Log.d("ConfigChangeActivity", "----onCreate----") ;
}
}

@Override
protected void onStart() {
super.onStart();
Log.d("ConfigChangeActivity", "----onStart----") ;
}

@Override
protected void onRestart() {
super.onRestart();
Log.d("ConfigChangeActivity", "----onRestart----") ;
}

@Override
protected void onResume() {
super.onResume();
Log.d("ConfigChangeActivity", "----onResume----") ;
}

@Override
protected void onPause() {
super.onPause();
Log.d("ConfigChangeActivity", "----onPause----") ;
}

@Override
protected void onStop() {
super.onStop();
Log.d("ConfigChangeActivity", "----onStop----") ;
}

@Override
protected void onDestroy() {
super.onDestroy();
Log.d("ConfigChangeActivity", "----onDestroy----") ;
}

/**
* onSaveInstanceState一般在onStop之前执行
* @param outState
*/
@Override
protected voidonSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("ConfigChangeActivity", "----onSaveInstanceState----") ;
        //在这里保存数据
outState.putString("extra_data","wzh!!!!!");
}

/**
* 一般在onRestoreInstanceState()或onCreate()里都可以获取onSaveInstanceState()保存过来的数据
* 但是onRestoreInstanceState()里的参数Bundle savedInstanceState是一定有值的,不必判断是否为null
* 而onCreate()里的参数Bundle savedInstanceState 有可能为null(正常启动时就为null),所以要额外判断是否为null
* 官方推荐用onRestoreInstanceState()
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String data = savedInstanceState.getString("extra_data","--empty--") ;
Log.d("ConfigChangeActivity", "----onRestoreInstanceState[restore]---- extra_data:" +data) ;
}
}
 
调试日志:
启动ConfigChangeActivity
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onCreate----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onStart----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onResume----

由横屏切换到竖屏
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onPause----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ---- onSaveInstanceState----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onStop----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onDestroy----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onCreate[restore]----   extra_data:wzh!!!!!
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onStart----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ---- onRestoreInstanceState[restore]----   extra_data:wzh!!!!!
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onResume----

由竖屏切换到横屏
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onPause----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ---- onSaveInstanceState----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onStop----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onDestroy----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onCreate[restore]----   extra_data:wzh!!!!!
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onStart----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ---- onRestoreInstanceState[restore]----    extra_data:wzh!!!!!
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onResume----

退出:
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onPause----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onStop----
    8816-8816/com.wzh.activitylifecycletest D/ConfigChangeActivity﹕ ----onDestroy----

总结:
           a,横竖屏切换都只是重新执行的一次生命周期,没有执行2次
           b, onSaveInstanceState在onPause()之后,onStop()之前执行
           c, onRestoreInstanceState在onStart()之后,和onResume()之前执行

2,内存资源不足时,Activity被系统回收
       这种情况,其数据储存和恢复过程和1是一样的,
       这个跟Activity的优先级有关
       

 



三:系统配置发生变化时,通过设置Activity的 android:configChanges属性,可以不使Activity重新创建
android:configChanges="orientation"
代码举例:
ConfigChangeActivity2.java
/**
* 这个测试的是系统配置改变,不重新创建Activity
* 设置Activity的android:configChanges属性
*/
public class ConfigChangeActivity2 extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_config_change2);
Log.d("ConfigChangeActivity2", "----onCreate----") ;
}

@Override
protected void onStart() {
super.onStart();
Log.d("ConfigChangeActivity2", "----onStart----") ;
}

@Override
protected void onRestart() {
super.onRestart();
Log.d("ConfigChangeActivity2", "----onRestart----") ;
}

@Override
protected void onResume() {
super.onResume();
Log.d("ConfigChangeActivity2", "----onResume----") ;
}

@Override
protected void onPause() {
super.onPause();
Log.d("ConfigChangeActivity2", "----onPause----") ;
}

@Override
protected void onStop() {
super.onStop();
Log.d("ConfigChangeActivity2", "----onStop----") ;
}

@Override
protected void onDestroy() {
super.onDestroy();
Log.d("ConfigChangeActivity2", "----onDestroy----") ;
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d("ConfigChangeActivity2", "----onConfigurationChanged ---- 屏幕方向:"+newConfig.orientation) ;
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("ConfigChangeActivity2", "----onSaveInstanceState----") ;
outState.putString("extra_data", "wzh!!!!!");
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);

String data = savedInstanceState.getString("extra_data","--empty--") ;
Log.d("ConfigChangeActivity2", "----onRestoreInstanceState[restore]---- extra_data:" +data) ;
}
}

<activity
android:name=".activity.ConfigChangeActivity2"
android:label="@string/title_activity_config_change2"
android:configChanges="orientation|screenSize">
</activity>

调试日志:

启动ConfigChangeActivity2
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onCreate----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onStart----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onResume----


设置 android:configChanges="orientation"  (由于没有限制 screenSize,Activity还是会被摧毁并重新创建)
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onPause----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onSaveInstanceState----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onStop----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onDestroy----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onCreate----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onStart----
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onRestoreInstanceState[restore]----    extra_data:wzh!!!!!
18807-18807/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onResume----



然后设置 android:configChanges="orientation|screenSize"  
  这里Activity没有重新来一遍生命周期,而是 调用了onConfigurationChanged()方法
  (说明api13以上的平台,screenSize" 也会导致activity摧毁并重建,所以api13及以后需要限制screenSize)
21015-21015/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onConfigurationChanged ----  屏幕方向: 2
  

点击back键,退出ConfigChangeActivity2
21015-21015/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onPause----
21015-21015/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onStop----
21015-21015/com.wzh.activitylifecycletest D/ConfigChangeActivity2﹕ ----onDestroy----



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值