Activity生命周期完全解析

转载请注明出处:https://my.oschina.net/landptf/blog/828116

生命周期是个老生常谈的问题了,今天做个汇总,全当是记个笔记,以后查找起来方便一些。下面我将分三个部分来介绍。

为了演示方便我创建了两个Activity:ActivityA ActivityB

除生命周期函数之外也包含了onSaveInstanceState、onRestoreInstanceState、onNewIntent、onConfigurationChanged的回调

#1. 特殊场景下的生命周期

###1.1 按电源键关屏

01-18 23:16:21.003 7037-7037/com.landptf.blog E/ActivityA: onPause()
01-18 23:16:21.033 7037-7037/com.landptf.blog E/ActivityA: onSaveInstanceState()
01-18 23:16:21.033 7037-7037/com.landptf.blog E/ActivityA: onStop()

###1.2 按Home键回到主界面

01-18 23:18:46.413 7037-7037/com.landptf.blog E/ActivityA: onPause()
01-18 23:18:46.693 7037-7037/com.landptf.blog E/ActivityA: onSaveInstanceState()
01-18 23:18:46.693 7037-7037/com.landptf.blog E/ActivityA: onStop()

###1.3 按菜单键或长按Home键查看后台程序列表

01-18 23:19:50.093 7037-7037/com.landptf.blog E/ActivityA: onPause()
01-18 23:19:50.173 7037-7037/com.landptf.blog E/ActivityA: onSaveInstanceState()
01-18 23:19:50.173 7037-7037/com.landptf.blog E/ActivityA: onStop()

###1.4 Android 7.0 分屏相关 长按后分屏将分别执行

01-18 10:36:50.950 1453-1453/com.landptf.blog E/ActivityA: onDestroy()
01-18 10:36:50.954 1453-1453/com.landptf.blog E/ActivityA: onCreate()
01-18 10:36:50.961 1453-1453/com.landptf.blog E/ActivityA: onStart()
01-18 10:36:50.961 1453-1453/com.landptf.blog E/ActivityA: onRestoreInstanceState()
01-18 10:36:50.962 1453-1453/com.landptf.blog E/ActivityA: onResume()
01-18 10:36:50.962 1453-1453/com.landptf.blog E/ActivityA: onPause()
01-18 10:36:50.995 1453-1453/com.landptf.blog E/ActivityA: onResume()
01-18 10:36:51.831 1453-1453/com.landptf.blog E/ActivityA: onPause()
01-18 10:36:54.355 1453-1453/com.landptf.blog E/ActivityA: onResume()

从log中可以看出,activity先销毁之后重建,并且执行两次焦点切换事件

然后反复点击屏幕上的两个应用焦点将来回切换

01-18 10:39:26.193 1453-1453/com.landptf.blog E/ActivityA: onPause()
01-18 10:39:28.400 1453-1453/com.landptf.blog E/ActivityA: onResume()
01-18 10:39:29.534 1453-1453/com.landptf.blog E/ActivityA: onPause()
01-18 10:39:30.437 1453-1453/com.landptf.blog E/ActivityA: onResume()

注:如果是视频类应用不可以在onPause()方法里暂停 ###1.5 屏幕旋转

  • 切横屏
01-18 10:44:27.840 1453-1453/com.landptf.blog E/ActivityA: onPause()
01-18 10:44:27.841 1453-1453/com.landptf.blog E/ActivityA: onSaveInstanceState()
01-18 10:44:27.859 1453-1453/com.landptf.blog E/ActivityA: onStop()
01-18 10:44:27.860 1453-1453/com.landptf.blog E/ActivityA: onDestroy()
01-18 10:44:27.871 1453-1453/com.landptf.blog E/ActivityA: onCreate()
01-18 10:44:27.877 1453-1453/com.landptf.blog E/ActivityA: onStart()
01-18 10:44:27.878 1453-1453/com.landptf.blog E/ActivityA: onRestoreInstanceState()
01-18 10:44:27.879 1453-1453/com.landptf.blog E/ActivityA: onResume()

Activity重建

  • 切竖屏 同上 与切横屏时完全相同的生命周期
  • 设置config为orientation|keyboardHidden|screenSize后切横竖屏
android:configChanges="orientation|keyboardHidden|screenSize"
01-18 11:15:50.523 30577-30577/com.landptf.blog E/ActivityA: onConfigurationChanged()

###1.6 内存不足导致被系统回收 当内存不足时会优先将处于后台的Activity回收,ActivityA在后台,ActivityB在前台时,若ActivityA被回收后按Back键返回到ActivityA时,ActivityA会重建,执行过程如下:

01-18 10:36:50.954 1453-1453/com.landptf.blog E/ActivityA: onCreate()
01-18 10:36:50.961 1453-1453/com.landptf.blog E/ActivityA: onStart()
01-18 10:36:50.961 1453-1453/com.landptf.blog E/ActivityA: onRestoreInstanceState()
01-18 10:36:50.962 1453-1453/com.landptf.blog E/ActivityA: onResume()

###1.7 新Activity未完全遮挡旧Activity时的生命周期

  • 设置ActivityB的theme为
android:theme="@style/Theme.AppCompat.Dialog"
01-18 11:29:05.977 10621-10621/com.landptf.blog E/ActivityA: onPause()
01-18 11:29:05.980 10621-10621/com.landptf.blog E/ActivityB: onCreate()
01-18 11:29:05.983 10621-10621/com.landptf.blog E/ActivityB: onStart()
01-18 11:29:05.983 10621-10621/com.landptf.blog E/ActivityB: onResume()
  • 在ActivityB的onCreate()方法中添加 getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 使其背景透明,此时从A启动B,生命周期如下:
01-18 11:41:12.200 22238-22238/com.landptf.blog E/ActivityA: onPause()
01-18 11:41:12.202 22238-22238/com.landptf.blog E/ActivityB: onCreate()
01-18 11:41:12.207 22238-22238/com.landptf.blog E/ActivityB: onStart()
01-18 11:41:12.208 22238-22238/com.landptf.blog E/ActivityB: onResume()

可以看到两种方式的生命周期完全相同,都不会执行ActivityA的onStop()方法

#2. 与启动模式相关的生命周期

该博客内容重点不在于讲解Activity的启动模式,有兴趣的同学可以自行学习

  • singleTop 设置ActivityA的launchMode为singleTop,首次启动ActivityA会执行
01-19 09:58:16.175 11336-11336/com.landptf.blog E/ActivityA: onCreate()
01-19 09:58:16.179 11336-11336/com.landptf.blog E/ActivityA: onStart()
01-19 09:58:16.179 11336-11336/com.landptf.blog E/ActivityA: onResume()

当ActivityA处于栈顶时,再次打开ActivityA后,会执行

01-19 09:58:18.903 11336-11336/com.landptf.blog E/ActivityA: onPause()
01-19 09:58:18.903 11336-11336/com.landptf.blog E/ActivityA: onNewIntent()
01-19 09:58:18.903 11336-11336/com.landptf.blog E/ActivityA: onResume()

首先失去焦点然后回调onNewIntent方法,并没有重建

  • singleTask 设置ActivityA的launchMode为singleTask执行如下操作 ActivityA -> ActivityB -> ActivityA ActivityA启动
01-19 10:04:49.923 16914-16914/com.landptf.blog E/ActivityA: onCreate()
01-19 10:04:49.927 16914-16914/com.landptf.blog E/ActivityA: onStart()
01-19 10:04:49.927 16914-16914/com.landptf.blog E/ActivityA: onResume()

ActivityB启动,此时ActivityA处于栈底,ActivityB处于栈顶

01-19 10:05:12.023 16914-16914/com.landptf.blog E/ActivityA: onPause()
01-19 10:05:12.027 16914-16914/com.landptf.blog E/ActivityB: onCreate()
01-19 10:05:12.031 16914-16914/com.landptf.blog E/ActivityB: onStart()
01-19 10:05:12.031 16914-16914/com.landptf.blog E/ActivityB: onResume()
01-19 10:05:12.415 16914-16914/com.landptf.blog E/ActivityA: onSaveInstanceState()
01-19 10:05:12.415 16914-16914/com.landptf.blog E/ActivityA: onStop()

再启动ActivityA

01-19 10:05:49.103 16914-16914/com.landptf.blog E/ActivityB: onPause()
01-19 10:05:49.107 16914-16914/com.landptf.blog E/ActivityA: onNewIntent()
01-19 10:05:49.107 16914-16914/com.landptf.blog E/ActivityA: onRestart()
01-19 10:05:49.107 16914-16914/com.landptf.blog E/ActivityA: onStart()
01-19 10:05:49.107 16914-16914/com.landptf.blog E/ActivityA: onResume()
01-19 10:05:49.467 16914-16914/com.landptf.blog E/ActivityB: onStop()
01-19 10:05:49.467 16914-16914/com.landptf.blog E/ActivityB: onDestroy()

前面两步都是正常的执行流程,重点看最后一步,从log中发现ActivityB执行了onDestory方法,因此可以断定ActivityB已经销毁,而ActivityA重建但是并没有执行onCreate方法替代的是onNewIntent方法

  • singleInstance 设置ActivityA的launchMode为singleInstance执行如下操作 ActivityA -> ActivityB -> ActivityA 前两步同上,我们直接看第三步的执行流程,此时ActivityA处于栈底,ActivityB处于栈顶
01-19 10:11:52.963 24180-24180/com.landptf.blog E/ActivityB: onPause()
01-19 10:11:52.963 24180-24180/com.landptf.blog E/ActivityA: onNewIntent()
01-19 10:11:52.963 24180-24180/com.landptf.blog E/ActivityA: onRestart()
01-19 10:11:52.963 24180-24180/com.landptf.blog E/ActivityA: onStart()
01-19 10:11:52.963 24180-24180/com.landptf.blog E/ActivityA: onResume()
01-19 10:11:53.735 24180-24180/com.landptf.blog E/ActivityB: onSaveInstanceState()
01-19 10:11:53.735 24180-24180/com.landptf.blog E/ActivityB: onStop()

可以看出区别在于ActivityB并没有执行onDestroy方法,也就是说ActivityB并没有销毁 此时按Back键返回,ActivityB回到了前台

01-19 10:15:45.947 28069-28069/com.landptf.blog E/ActivityA: onPause()
01-19 10:15:45.951 28069-28069/com.landptf.blog E/ActivityB: onRestart()
01-19 10:15:45.951 28069-28069/com.landptf.blog E/ActivityB: onStart()
01-19 10:15:45.951 28069-28069/com.landptf.blog E/ActivityB: onResume()
01-19 10:15:46.747 28069-28069/com.landptf.blog E/ActivityA: onStop()
01-19 10:15:46.747 28069-28069/com.landptf.blog E/ActivityA: onDestroy()

此时ActivityA已销毁,再次按Back键则返回到主界面

#3. 正常流程的生命周期 正常流程上的生命周期,也就是设置launchMode为standard(默认启动模式,可以省略) 首先启动ActivityA

01-19 10:20:36.159 318-318/com.landptf.blog E/ActivityA: onCreate()
01-19 10:20:36.163 318-318/com.landptf.blog E/ActivityA: onStart()
01-19 10:20:36.163 318-318/com.landptf.blog E/ActivityA: onResume()

再启动ActivityB

01-19 10:21:15.323 318-318/com.landptf.blog E/ActivityA: onPause()
01-19 10:21:15.323 318-318/com.landptf.blog E/ActivityB: onCreate()
01-19 10:21:15.327 318-318/com.landptf.blog E/ActivityB: onStart()
01-19 10:21:15.327 318-318/com.landptf.blog E/ActivityB: onResume()
01-19 10:21:15.727 318-318/com.landptf.blog E/ActivityA: onSaveInstanceState()
01-19 10:21:15.727 318-318/com.landptf.blog E/ActivityA: onStop()

这里面注意一点ActivityA的onPause方法在ActivityB的onCreate方法之前执行,因此不要在onPause方法里做耗时操作,否则会影响新Activity的启动时间 按Back键返回到ActivityA

01-19 10:23:32.755 318-318/com.landptf.blog E/ActivityB: onPause()
01-19 10:23:32.755 318-318/com.landptf.blog E/ActivityA: onRestart()
01-19 10:23:32.755 318-318/com.landptf.blog E/ActivityA: onStart()
01-19 10:23:32.755 318-318/com.landptf.blog E/ActivityA: onResume()
01-19 10:23:33.203 318-318/com.landptf.blog E/ActivityB: onStop()
01-19 10:23:33.203 318-318/com.landptf.blog E/ActivityB: onDestroy()

同样是ActivityB的onPause方法先执行

以上便是我能想到的有关Activity生命周期相关的内容,有错误或者不足的地方欢迎大家指出

调试代码已上传github,欢迎访问

    原文作者:移动开发
    原文地址: https://my.oschina.net/landptf/blog/828116
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞