Android知识重温之生命周期

2,023 阅读12分钟

生命周期回顾

Activity和Fragment的生命周期是Android开发的基础,也是其中最重要的一部分,掌握了各种情景下的生命周期,能够更好的帮助我们解决问题

Activity的生命周期方法以及常用方法

image

onCreate():

当activity是被创建时候,会自动运行该方法。该方法做一些初始化动作.

onRestart():

把activity从onStop状态唤醒时,会用onRestart方法,该方法优先于再次运行的onStart,运行完onRestart之后运行onStart。

onStart():

当activity对用户可见时会调用onStart,当activity在前台显示时,会运行onResume

onResume():

当activity开始与用户交互时,会调用onResume,并且为了用户操作此时该activity位于activity栈的顶部。

onPause():

当一个activity运行到onResume方法后,不管是这个activity要销毁还是要暂停或停止,都会调用该方法。

onStop():

当这个activity完全看不见的时候,会调用onStop方法,因为另一个activity会调用onResume并且覆盖这个activity。

onDestroy():

当activity销毁前会调用该方法,比如发生如下情况:activity调用了finish()方法来结束这个activity,或者因为系统为了节省空间而临时销毁这个activity,这两个情况可以通过isFinishing()方法判断

onSaveInstanceState():

当用户按下Home键或者程序异常退出以及屏幕旋转时会调用此方法进行保存数据

onRestoreInstanceState():

屏幕旋转或异常退出后重新打开会调用此方法,进行恢复数据

onConfigurationChanged():

AndroidManifest设置configChanges属性后,会调用此方法

onNewInstent():

非默认模式时,启动一个已存在的Activity时候,会先调用这个方法。需要在此方法中更新intent

onActivityResult():

A界面调用startActivityForResult()方法跳转B界面,B界面返回时会调用此方法,进行对B界面返回的数据进行处理

Activity启动模式

standard(默认)

默认的模式,每次新建Activity时候都会在栈中加入一个Activity。

具体生命周期调用是onCreate()->onStart()->onResume()

singleTop

如果一个Activity已经存在,并且处于任务栈的栈顶。那么再启动这个Activity时不会创建新的实例,而是直接调用当前Activity的onNewIntent()方法,启动。使用场景多在商品详情页

具体的生命周期是onNewIntent()->onResume()。

singleTask

栈内唯一的启动方式。如果任务栈中已经存在当前Activity,那么直接启动当前Activity,不创建新的实例。同时在当前Activity栈之上的Activity会被移除。可以用来设置主页面。

具体生命周期调用是onNewIntent()->onRestart()->onStart()->onResume()。

singleInstance

在一个新的栈中打开一个Activity。可以用来共享Activity。如在一个应用中创建了一个Activity,然后在另一个应用中页可以再以这个模式建立这个Activity时,不会重复创建。

具体生命周期调用是onNewIntent()->onRestart()->onStart()->onResume()。

普通Activity的生命周期

Activity的创建

onCreate() -> onStart() -> onResume()

点击返回键

onPause() -> onStop() -> onDestroy()

按Home键时Activity的生命周期

Activity的创建

onCreate() -> onStart() -> onResume()

点击Home键或锁屏

onPause() -> onSaveInstanceState() -> onStop()

切换回来或解锁

onRestart() -> onStart() -> onResume()

Activity横竖屏旋转生命周期

1. AndroidManifest没有设置configChanges属性:

onPause() -> onSaveInstanceState() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()

2.android:configChanges="orientation"

Android 6.0 : onPause() -> onSaveInstanceState() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()

Android 7.0 : onConfigurationChanged() -> onPause() -> onSaveInstanceState() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()

Android 8.0 9.0 : onConfigurationChanged()

设置android:configChanges="orientation|keyboardHidden|screenSize" 只会调用只调用了onConfigurationChanged()方法,Activity的其他生命周期方法都不会调用

3.android:configChanges="orientation|keyboardHidden|screenSize"

Android 6.0 7.0 8.0 9.0 : 只调用了onConfigurationChanged() 方法

4.android:configChanges="orientation|screenSize"

情景4和情景3的结果是一样的

5.android:configChanges="orientation|keyboardHidden"

情景5和情景2是一样的

结论

  1. 不设置configChanges属性不会回调onConfigurationChanged,且切屏的时候会回调生命周期方法
  2. 只有设置了orientation 和 screenSize 才不会走生命周期方法,只回调onConfigurationChanged方法
  3. 设置orientation,没有设置screenSize,切屏会回调onConfigurationChanged,8.0 和 9不会调用生命周期方法,8.0以下的还是会调用生命周期方法
configChanges属性
1. orientation 屏幕在纵向和横向间旋转
2.keyboardHidden 键盘显示或隐藏
3.screenSize 屏幕大小改变了
4.fontScale 用户变更了首选的字体大小
5.locale 用户选择了不同的语言设定
6.keyboard 键盘类型变更,例如手机从12键盘切换到全键盘
7.touchscreen或navigation 键盘或导航方式变化,一般不会发生这样的事件

screenOrientation属性
1. unspecified 默认值,由系统判断状态自动切换
2. landscape 横屏
3. portrait 竖屏
4. user 用户当前设置的orientation值
5. behind 下一个要显示的Activity的orientation值
6. sensor 使用传感器 传感器的方向
7. nosensor 不使用传感器 基本等同于unspecified

Activity异常结束生命周期

异常情况导致Activity被杀死并重建

onPause() -> onSaveInstanceState() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()

两个普通Activity间跳转时的生命周期

打开程序: MainActivity: onCreate() -> onStart() -> onResume()

跳转到SecondActivity

  1. MainActivity: onPause()
  2. SecondActivity: onCreate() -> onStart() -> onResume()
  3. MainActivity: onSaveInstanceState() -> onStop()

点击back键返回MainActivity:

  1. SecondActivity: onPause()
  2. MainActivity: onRestart() -> onStart() -> onResume()
  3. SecondActivity: onStop() -> onDestroy()

Activity跳转到透明背景Activity的生命周期

打开程序: MainActivity: onCreate() -> onStart() -> onResume()

跳转到SecondActivity(透明背景)

  1. SecondActivity: onPause()
  2. MainActivity: onRestart() -> onStart() -> onResume()

点击back键返回MainActivity:

  1. SecondActivity: onPause()
  2. MainActivity: onResume()
  3. SecondActivity: onStop() -> onDestroy()

Activity弹出和结束小窗口时的生命周期

打开程序: MainActivity: onCreate() -> onStart() -> onResume()

打开对话框

  1. SecondActivity: onPause()
  2. MainActivity: onRestart() -> onStart() -> onResume()

结束对话框

  1. SecondActivity: onPause()
  2. MainActivity: onResume()
  3. SecondActivity: onStop() -> onDestroy()

Fragment的生命周期方法

Fragment生命周期图

Fragment生命周期图

Fragment与Activity生命周期的关系图

Fragment与Activity生命周期关系图

Fragment生命周期方法

1. onHiddenChanged():

当 Fragment 调用 hide() 、 show() 时回调

2. setUserVisibleHint():

当 Fragment 与 ViewPager 结合使用时,切换 Pager 时回调

3. onAttach():

Fragment 关联到 Activity 时回调,此时 Activity 已经与 Fragment 关联,通过 Context 向下转型,就可以与 Activity 通信,当然也可以使用 getActivity(),前提是这个 fragment 已经和宿主的 activity 关联,并且没有脱离,此方法只能调用一次

4. onCreate():

系统创建 Fragment 的时候回调,介于 onAttach() 和 onCreateView() 之间,一般用于初始化一些数据,值得注意的是,此时 Activity 还在创建中,因此不能在执行一些跟 Activity UI 相关的操作,否则,会出现一些难以预料的问题,比如:NullPointException,如果要对 Activity 上的 UI 进行操作,建议在 onActivityCreated() 中操作

5. onCreateView():

创建 Fragment 需要显示的 View,默认返回 null。当返回的 View 不为 null 时,View 被销毁时会调用 onDestroyView(),此处应该只进行布局的初始化,而不应该执行耗时操作,如网络请求、数据库读取

6. onViewCreated():

该方法在 onCreateView() 之后会被立即执行,此时可以对 View 对象进行赋值,当然在 onCreateView() 中也可以执行

7. onActivityCreated():

当 Activity 执行完 onCreate() 方法后调用,此时可以执行与 Activity 相关的 UI 操作

8. onStart():

同Activity生命周期

9. onResume():

同Activity生命周期

10. onPause():

同Activity生命周期

11. onStop():

同Activity生命周期

12. onDestroyView():

表示销毁 Fragment 相关联的 UI 布局,清除所有跟视图相关的资源。

13. onDestroy():

销毁 Fragment 对象的时候调用,一般是调用 Activity 的 onDestroy() 的时候执行

14. onDetach():

解除 Fragment 与 Activity 的关联时调用,在Activity 的 onDestroy()时候执行

replace()时的生命周期

程序运行并显示第一个Fragment:

E/AddReplaceActivity: onCreate()
E/Fragment1: onAttach()
E/Fragment1: onCreate()
E/Fragment1: onCreateView()
E/Fragment1: onViewCreated()
E/Fragment1: onActivityCreated()
E/Fragment1: onStart()
E/AddReplaceActivity: onStart()
E/AddReplaceActivity: onResume()
E/Fragment1: onResume()

显示第二个Fragment:

E/Fragment2: onAttach()
E/Fragment2: onCreate()
E/Fragment1: onPause()
E/Fragment1: onStop()
E/Fragment1: onDestroyView()
E/Fragment1: onDestroy()
E/Fragment1: onDetach()
E/Fragment2: onCreateView()
E/Fragment2: onViewCreated()
E/Fragment2: onActivityCreated()
E/Fragment2: onStart()
E/Fragment2: onResume()

点击返回键结束Activity

E/Fragment2: onPause()
E/AddReplaceActivity: onPause()
E/Fragment2: onStop()
E/AddReplaceActivity: onStop()
E/Fragment2: onDestroyView()
E/Fragment2: onDestroy()
E/Fragment2: onDetach()
E/AddReplaceActivity: onDestroy()

add(), hide()和show()时的生命周期

情景1: 启动程序,把5个Fragment全部添加到FragmentTransaction中,并进行切换

启动程序,把5个Fragment全部添加到FragmentTransaction中,并显示第一个Fragment:

E/AddReplaceActivity: onCreate()
E/Fragment1: onAttach()
E/Fragment1: onCreate()
E/Fragment2: onAttach()
E/Fragment2: onCreate()
E/Fragment3: onAttach()
E/Fragment3: onCreate()
E/Fragment4: onAttach()
E/Fragment4: onCreate()
E/Fragment5: onAttach()
E/Fragment5: onCreate()
E/Fragment1: onCreateView()
E/Fragment1: onViewCreated()
E/Fragment1: onActivityCreated()
E/Fragment2: onCreateView()
E/Fragment2: onViewCreated()
E/Fragment2: onActivityCreated()
E/Fragment3: onCreateView()
E/Fragment3: onViewCreated()
E/Fragment3: onActivityCreated()
E/Fragment4: onCreateView()
E/Fragment4: onViewCreated()
E/Fragment4: onActivityCreated()
E/Fragment5: onCreateView()
E/Fragment5: onViewCreated()
E/Fragment5: onActivityCreated()
E/Fragment1: onHiddenChanged() =>  true
E/Fragment2: onHiddenChanged() =>  true
E/Fragment3: onHiddenChanged() =>  true
E/Fragment4: onHiddenChanged() =>  true
E/Fragment5: onHiddenChanged() =>  true
E/Fragment1: onHiddenChanged() =>  false
E/Fragment1: onStart()
E/Fragment2: onStart()
E/Fragment3: onStart()
E/Fragment4: onStart()
E/Fragment5: onStart()
E/AddReplaceActivity: onStart()
E/AddReplaceActivity: onResume()
E/Fragment1: onResume()
E/Fragment2: onResume()
E/Fragment3: onResume()
E/Fragment4: onResume()
E/Fragment5: onResume()

切换Fragment:

E/Fragment1: onHiddenChanged() =>  true
E/Fragment2: onHiddenChanged() =>  false

结束Activity:

E/Fragment1: onPause()
E/Fragment2: onPause()
E/Fragment3: onPause()
E/Fragment4: onPause()
E/Fragment5: onPause()
E/AddReplaceActivity: onPause()
E/Fragment1: onStop()
E/Fragment2: onStop()
E/Fragment3: onStop()
E/Fragment4: onStop()
E/Fragment5: onStop()
E/AddReplaceActivity: onStop()
E/Fragment1: onDestroyView()
E/Fragment1: onDestroy()
E/Fragment1: onDetach()
E/Fragment2: onDestroyView()
E/Fragment2: onDestroy()
E/Fragment2: onDetach()
E/Fragment3: onDestroyView()
E/Fragment3: onDestroy()
E/Fragment3: onDetach()
E/Fragment4: onDestroyView()
E/Fragment4: onDestroy()
E/Fragment4: onDetach()
E/Fragment5: onDestroyView()
E/Fragment5: onDestroy()
E/Fragment5: onDetach()
E/AddReplaceActivity: onDestroy()
情景2: 动态往FragmentTransaction里面添加Fragment并进行切换

程序启动,并显示第一个Fragment:

E/AddReplaceActivity: onCreate()
E/Fragment1: onAttach()
E/Fragment1: onCreate()
E/Fragment1: onHiddenChanged() =>  true
E/Fragment1: onCreateView()
E/Fragment1: onViewCreated()
E/Fragment1: onActivityCreated()
E/Fragment1: onHiddenChanged() =>  false
E/Fragment1: onStart()
E/AddReplaceActivity: onStart()
E/AddReplaceActivity: onResume()
E/Fragment1: onResume()

切换到未创建实例的Fragment:

E/Fragment1: onHiddenChanged() =>  true
E/Fragment2: onAttach()
E/Fragment2: onCreate()
E/Fragment2: onHiddenChanged() =>  true
E/Fragment2: onCreateView()
E/Fragment2: onViewCreated()
E/Fragment2: onActivityCreated()
E/Fragment2: onStart()
E/Fragment2: onResume()
E/Fragment2: onHiddenChanged() =>  false

切换到已创建实例的Fragment:

E/Fragment1: onHiddenChanged() =>  true
E/Fragment2: onHiddenChanged() =>  false

结束Activity:

E/Fragment1: onPause()
E/Fragment2: onPause()
E/Fragment3: onPause()
E/AddReplaceActivity: onPause()
E/Fragment1: onStop()
E/Fragment2: onStop()
E/Fragment3: onStop()
E/AddReplaceActivity: onStop()
E/Fragment1: onDestroyView()
E/Fragment1: onDestroy()
E/Fragment1: onDetach()
E/Fragment2: onDestroyView()
E/Fragment2: onDestroy()
E/Fragment2: onDetach()
E/Fragment3: onDestroyView()
E/Fragment3: onDestroy()
E/Fragment3: onDetach()
E/AddReplaceActivity: onDestroy()

备注: add(), hide()和show()方式的懒加载方案可以针对onHiddenChanged()方法去实现

ViewPager+Fragment时Fragment切换时的生命周期

场景1: 没有设置 viewPager.offscreenPageLimit = 5

程序启动,并显示第一个Fragment

E/ViewPagerActivity: onCreate()
E/ViewPagerActivity: onStart()
E/ViewPagerActivity: onResume()
E/Fragment1: setUserVisibleHint() =>  false
E/Fragment2: setUserVisibleHint() =>  false
E/Fragment1: setUserVisibleHint() =>  true
E/Fragment1: onAttach()
E/Fragment1: onCreate()
E/Fragment2: onAttach()
E/Fragment2: onCreate()
E/Fragment1: onCreateView()
E/Fragment1: onViewCreated()
E/Fragment1: onActivityCreated()
E/Fragment1: onStart()
E/Fragment1: onResume()
E/Fragment2: onCreateView()
E/Fragment2: onViewCreated()
E/Fragment2: onActivityCreated()
E/Fragment2: onStart()
E/Fragment2: onResume()

切换第二个: 会预加载第三个页面

E/Fragment3: setUserVisibleHint() =>  false
E/Fragment1: setUserVisibleHint() =>  false
E/Fragment2: setUserVisibleHint() =>  true
E/Fragment3: onAttach()
E/Fragment3: onCreate()
E/Fragment3: onCreateView()
E/Fragment3: onViewCreated()
E/Fragment3: onActivityCreated()
E/Fragment3: onStart()
E/Fragment3: onResume()

切换第三个: 预加载第四个页面,并且第一个页面会调用 onPause()->onStop()->onDestroyView()

E/Fragment4: setUserVisibleHint() =>  false
E/Fragment2: setUserVisibleHint() =>  false
E/Fragment3: setUserVisibleHint() =>  true
E/Fragment4: onAttach()
E/Fragment4: onCreate()
E/Fragment1: onPause()
E/Fragment1: onStop()
E/Fragment1: onDestroyView()
E/Fragment4: onCreateView()
E/Fragment4: onViewCreated()
E/Fragment4: onActivityCreated()
E/Fragment4: onStart()
E/Fragment4: onResume()

切换第四个: 预加载第五个页面,并且第二个页面会调用 onPause()->onStop()->onDestroyView()

E/Fragment5: setUserVisibleHint() =>  false
E/Fragment3: setUserVisibleHint() =>  false
E/Fragment4: setUserVisibleHint() =>  true
E/Fragment5: onAttach()
E/Fragment5: onCreate()
E/Fragment2: onPause()
E/Fragment2: onStop()
E/Fragment2: onDestroyView()
E/Fragment5: onCreateView()
E/Fragment5: onViewCreated()
E/Fragment5: onActivityCreated()
E/Fragment5: onStart()
E/Fragment5: onResume()

结束Activity

E/Fragment4: onPause()
E/Fragment5: onPause()
E/Fragment3: onPause()
E/ViewPagerActivity: onPause()
E/Fragment4: onStop()
E/Fragment5: onStop()
E/Fragment3: onStop()
E/ViewPagerActivity: onStop()
E/Fragment4: onDestroyView()
E/Fragment4: onDestroy()
E/Fragment4: onDetach()
E/Fragment5: onDestroyView()
E/Fragment5: onDestroy()
E/Fragment5: onDetach()
E/Fragment3: onDestroyView()
E/Fragment3: onDestroy()
E/Fragment3: onDetach()
E/Fragment1: onDestroy()
E/Fragment1: onDetach()
E/Fragment2: onDestroy()
E/Fragment2: onDetach()
E/ViewPagerActivity: onDestroy()
情景2: 设置 viewPager.offscreenPageLimit = 5

程序启动,并显示第一个:

E/ViewPagerActivity: onCreate()
E/ViewPagerActivity: onStart()
E/ViewPagerActivity: onResume()
E/Fragment1: setUserVisibleHint() =>  false
E/Fragment2: setUserVisibleHint() =>  false
E/Fragment3: setUserVisibleHint() =>  false
E/Fragment4: setUserVisibleHint() =>  false
E/Fragment5: setUserVisibleHint() =>  false
E/Fragment1: setUserVisibleHint() =>  true
E/Fragment1: onAttach()
E/Fragment1: onCreate()
E/Fragment2: onAttach()
E/Fragment2: onCreate()
E/Fragment3: onAttach()
E/Fragment3: onCreate()
E/Fragment4: onAttach()
E/Fragment4: onCreate()
E/Fragment5: onAttach()
E/Fragment5: onCreate()
E/Fragment1: onCreateView()
E/Fragment1: onViewCreated()
E/Fragment1: onActivityCreated()
E/Fragment1: onStart()
E/Fragment1: onResume()
E/Fragment2: onCreateView()
E/Fragment2: onViewCreated()
E/Fragment2: onActivityCreated()
E/Fragment3: onCreateView()
E/Fragment3: onViewCreated()
E/Fragment3: onActivityCreated()
E/Fragment4: onCreateView()
E/Fragment4: onViewCreated()
E/Fragment4: onActivityCreated()
E/Fragment5: onCreateView()
E/Fragment5: onViewCreated()
E/Fragment5: onActivityCreated()
E/Fragment2: onStart()
E/Fragment2: onResume()
E/Fragment3: onStart()
E/Fragment3: onResume()
E/Fragment4: onStart()
E/Fragment4: onResume()
E/Fragment5: onStart()
E/Fragment5: onResume()

切换:

E/Fragment1: setUserVisibleHint() =>  false
E/Fragment2: setUserVisibleHint() =>  true

结束:

E/Fragment1: onPause()
E/Fragment2: onPause()
E/Fragment3: onPause()
E/Fragment4: onPause()
E/Fragment5: onPause()
E/ViewPagerActivity: onPause()
E/Fragment1: onStop()
E/Fragment2: onStop()
E/Fragment3: onStop()
E/Fragment4: onStop()
E/Fragment5: onStop()
E/ViewPagerActivity: onStop()
E/Fragment1: onDestroyView()
E/Fragment1: onDestroy()
E/Fragment1: onDetach()
E/Fragment2: onDestroyView()
E/Fragment2: onDestroy()
E/Fragment2: onDetach()
E/Fragment3: onDestroyView()
E/Fragment3: onDestroy()
E/Fragment3: onDetach()
E/Fragment4: onDestroyView()
E/Fragment4: onDestroy()
E/Fragment4: onDetach()
E/Fragment5: onDestroyView()
E/Fragment5: onDestroy()
E/Fragment5: onDetach()
E/ViewPagerActivity: onDestroy()

备注: ViewPager方式的懒加载方案可以针对setUserVisibleHint()方法去实现

Activity容器 + Navigation

程序启动

E/NavigationActivity: onCreate()
E/Fragment1: onAttach()
E/Fragment1: onCreate()
E/Fragment1: onCreateView()
E/Fragment1: onViewCreated()
E/Fragment1: onActivityCreated()
E/Fragment1: onStart()
E/NavigationActivity: onStart()
E/NavigationActivity: onResume()
E/Fragment1: onResume()

跳转界面

E/Fragment2: onAttach()
E/Fragment2: onCreate()
E/Fragment2: onCreateView()
E/Fragment2: onViewCreated()
E/Fragment2: onActivityCreated()
E/Fragment2: onStart()
E/Fragment2: onResume()
E/Fragment1: onPause()
E/Fragment1: onStop()
E/Fragment1: onDestroyView()

返回上一个界面

E/Fragment1: onCreateView()
E/Fragment1: onViewCreated()
E/Fragment1: onActivityCreated()
E/Fragment1: onStart()
E/Fragment1: onResume()
E/Fragment2: onPause()
E/Fragment2: onStop()
E/Fragment2: onDestroyView()
E/Fragment2: onDestroy()
E/Fragment2: onDetach()

结束Activity

E/Fragment1: onPause()
E/NavigationActivity: onPause()
E/Fragment1: onStop()
E/NavigationActivity: onStop()
E/Fragment1: onDestroyView()
E/Fragment1: onDestroy()
E/Fragment1: onDetach()
E/NavigationActivity: onDestroy()

Service生命周期方法

image

1. onCreate():

首次创建服务时,系统将调用此方法。如果服务已在运行,则不会调用此方法,该方法只调用一次。

2. onStartCommand():

当另一个组件通过调用startService()请求启动服务时,系统将调用此方法

3. onBind():

当另一个组件通过调用bindService()与服务绑定时,系统将调用此方法。

4. onUnbind():

当另一个组件通过调用unbindService()与服务解绑时,系统将调用此方法。

5. onRebind():

当旧的组件与服务解绑后,另一个新的组件与服务绑定,onUnbind()返回true时,系统将调用此方法。

6. onDestroy():

当服务不再使用且将被销毁时,系统将调用此方法。

启动/绑定Service时的生命周期

1. startService()

启动服务 startService() : onCreate() -> onStartCommand() (多次调用startService()方法时,onStartCommand()方法会执行多次)

停止服务 stopService(): onDestroy()

2. bindService()

绑定服务 bindService(): onCreate() —> onBind()

解绑服务 unbindService(): onUnbind() —> onDestroy()

熟练掌握这些生命周期能够帮助我们解决很多问题