android整个生命周期有4种状态、7个重要方法、3个嵌套循环。
一、四种状态
1、活动(Activity / Running)状态
当Activity运行在屏幕前台(处于当前任务活动栈的最上面),此时它获取了焦点能响应用户的操作,属于运行状态,同一个时刻只会有一个Activity处于活动或运行状态。
2、暂停(Paused)状态
当Activity失去焦点但仍对用户可见(如在它之上有一个透明的Activity或Toast、AlertDialog等弹出窗口时)它处于暂停状态。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接),但是当系统内存极小时可以被系统杀掉。
3、停止(Stopped)状态
完全被另一个Activity遮挡时处于停止状态,它仍然保留着所有的状态和成员信息。只是对用户不可见,当其他地方需要内存时它往往被系统杀掉。
4、非活动(Dead)状态
Activity尚未被启动、已经被手动终止,或已经被系统回收时处于非活动的状态,要手动终止Activity,可以在程序中调用”finish“方法。如果是(按根据内存不足时的回收规则)被系统回收,可能是因为内存不足了。
二、7个重要方法
(1)、onCreate(Bundle savedInstanceState)
整个生命周期只调用一次这个方法,通常用于初始化设置:
a、为Activity设置所要使用的布局文件;
b、为按钮绑定监听器等静态的设置操作。
(2)、onStart()
当Activity可见未获得用户焦点不能交互时系统会调用;
(3)、onRestart()
当Activity已经停止然后重新启动时系统会调用;
(4)、onResume()
当Activity可见且获得用户焦点能交互时系统会调用;
(5)、onPauuse()
当系统启动另外一个新的Activity时,在新Activity启动之前被系统调用保存现有的Activity中的持久数据、停止动画等,这个实现方法必须非常快。当系统而不是用户自己处于回收内存时,关闭了activity之后,用户会期望当他再次回到这个Activity时,它仍保存着上次离开时的样子,此时用到了onSaveInstanceState()方法,onSaveInstanceState()用来保存Activity被杀之前的状态,在onPause()之前被触发,当系统为了节省内存销毁了Activity(用户本不想销毁)时就需要重写这个方法了,当次Activity再次被实例化时会通过onCreate(Bundle savedInstanceState)将已经保存的临时状态数据传入,因为onSaveInstanceState()方法不总是被调用,触发条件为(按下HOME键,按下电源按键关闭屏幕,横竖屏切换情况下),你应该仅重写onSaveInstanceState()来记录activity的临时状态,而不是持久的数据。应该使用onPause()来存储持久数据。
(6)、onStop()
当Activity被新的Activity完全覆盖不可见时被系统调用
(7)、onDestroy()
当Activity(用户调用finish()或系统由于内存不足)被系统销毁杀掉时系统会调用,(整个生命周期只调用1次)用来释放onCreate()方法中创建的资源,如结束线程等。
正常启动一个程序会执行:onCreate() --> onStart() --> onResume()
一个Activity启动另一个Activity时:onPause() --> onStop(),再返回时:onRestart() --> onStart() --> onResume()
程序按back退出:onPause() --> onStop() --> onDestroy(),再次进入时:onCreate() --> onStart() --> onResume()
程序按home退出:onPause() --> onStop(),再次进入:onRestart() --> onStart() --> onResume()
三、3个嵌套循环
1、Activity完整的生命周期:从第一次调用onCreate()开始直到调用onDestroy()结束;
2、Activity的可视生命周期:从调用onStart()到相应的调用onStop(),在这两个方法之间,可以保持显示Activity所需要的资源。如在onStart()中注册一个广播接收者监听影响你的UI的改变,在onStop()中注销;
3、Activity的前台生命周期:从调用onResume()到相应的调用onPause()。
横竖屏切换时,生命周期中各个方法的调用情况:
1、运行Activity时:
onCreate() --> onStart() --> onResume()
2、crtl+f12切换成横屏时:
onSaveInstanceState() --> onPause() --> onStop() --> onDestroy() --> onCreate() --> onStart() --> onRestoreInstanceState() --> onResume()
3、再按crtl+f12切换成竖屏时:
onSaveInstanceState() --> onPause() --> onStop() --> onDestroy() --> onCreate() --> onStart() --> onRestoreInstanceState() --> onResume()
onSaveInstanceState() --> onPause() --> onStop() --> onDestroy() --> onCreate() --> onStart() --> onRestoreInstanceState() --> onResume()
执行了2次相同的方法。
4、修改AndroidManifest.xml,把该Activity添加android:configChanges="orientation",执行步骤2:
onSaveInstanceState() --> onPause() --> onStop() --> onDestroy() --> onCreate() --> onStart() --> onRestoreInstanceState() --> onResume()
5、再执行步骤3:
onSaveInstanceState() --> onPause() --> onStop() --> onDestroy() --> onCreate() --> onStart() --> onRestoreInstanceState() --> onResume() --> onConfigurationChanged()
6、把步骤4中的android:configChanges="orientation"改成android:configChanges="orientation|keyboardHidden",执行步骤2:
onConfigurationChanged()
7、执行步骤3:
onConfigurationChanged() --> onConfigurationChanged()
总结:
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次;
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次;
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged()方法。
补充:
当前Activity产生事件弹出Toast和AlertDialog时,Activity的生命周期不会改变;
Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState() --> onPause() --> onStop(),再次进入激活状态时:onRestart() --> onStart() --> onResume()。