Activity生命周期的自测(对网上一些说法进行纠正)
发现网上一些对于生命周期的说法有问题,于是自己写代码测试一下,并结合官网的说明,对一些说法进行纠正。
1. 基本的生命周期
以下来自官网的说明:
https://developer.android.com/guide/components/activities.html
public class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
//注意,这里说的是将要变为可见,并不是已经可见了
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible (it is now "resumed").
//网上有人说,onResume代表已经可以与用户交互,这是错的,
//官网的原话是:在 Activity 即将开始与用户进行交互之前调用。
//这句话应该理解成,onResume执行完成才可以与用户交互
}
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is about to be "paused").
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now "stopped")
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
}
2.横竖屏切换时候activity的生命周期
1、新建一个Activity,并把各个生命周期打印出来
public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_activity);
//设置一个点击,测试弹窗会不会导致生命周期变化
TextView tv = (TextView)findViewById(R.id.tv);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Toast.makeText(SplashActivity.this, "ToasTest", Toast.LENGTH_LONG);
new AlertDialog.Builder(SplashActivity.this).setTitle("test").setMessage("hdghdgh").show();
}
});
Log.i("WQW", "onCreate");
}
@Override
protected void onStart() {
super.onStart();
Log.i("WQW", "onStart");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i("WQW", "onRestart");
}
@Override
protected void onResume() {
super.onResume();
Log.i("WQW", "onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.i("WQW", "onPause");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i("WQW", "onSaveInstanceState");
}
@Override
protected void onStop() {
super.onStop();
Log.i("WQW", "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("WQW", "onDestroy");
}
@Override
public void onLowMemory() {
super.onLowMemory();
Log.i("WQW", "onLowMemory");
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
Log.i("WQW", "onTrimMemory");
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
Log.i("WQW", "onConfigurationChanged");
super.onConfigurationChanged(newConfig);
}
}
2、运行Activity,得到如下信息
onCreate-->
onStart-->
onResume-->
3、执行横竖屏切换,网上说切竖屏会执行生命周期两次,在5.0、6.0上测试,发现并不会执行两次。
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
4、修改AndroidManifest.xml,把该Activity添加 android:configChanges="orientation",执行横竖屏切换,
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
为什么是这种结果呢?往下看第5步吧。
5、把步骤4的android:configChanges="orientation" 改成 android:configChanges="orientation||screenSize",执行横竖屏切换,就只打印onConfigChanged。
onConfigurationChanged-->
在API 13以上,需要加入screenSize才能正确响应onConfigurationChanged,下面是官网的原话:https://developer.android.com/guide/topics/resources/runtime-changes.html
注意:从 Android 3.2(API 级别 13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。
因此,在开发针对 API 级别 13 或更高版本系统的应用时,
若要避免由于设备方向改变而导致运行时重启(正如 minSdkVersion 和 targetSdkVersion 属性中所声明),
则除了 "orientation" 值以外,您还必须添加 "screenSize" 值。
即,您必须声明 android:configChanges="orientation|screenSize"。
但是,如果您的应用是面向 API 级别 12 或更低版本的系统,
则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重启 Activity)。
总结:
-
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次。这个说法是错的,都只执行一次,当然两次的情况可能是老版本,我没有测试。
-
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次。
-
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法。经测试,这个设置是没有用的,正确的应该是配置成android:configChanges="orientation||screenSize
-
4、当前Activity弹出Toast和AlertDialog的时候Activity的生命周期不会有改变.这个是对的,但是和官网上说的不一样。官网上的原话是这么说的:
Activity 可频繁转入和转出前台—例如,当设备转入休眠状态或出现对话框时,系统会调用 onPause()。
而经过实际测试,并不会改变生命周期,这个地方有点纳闷,难道官网也不严谨,或者是我哪里有问题?欢迎高手测试指出。
-
5、Activity运行时按下HOME键(跟被完全覆盖是一样的):
onPause --> onSaveInstanceState --> //注意这里的顺序,onPause到前面去了。 onStop onRestart --> onStart---> onResume
-
Activity未被完全覆盖只是失去焦点:onPause--->onResume