Activity的生命周期和启动模式
Activity的生命周期分析
- 典型情况下的生命周期。是指在用户参与的情况下,Activity所经过的生命周期的改变。
- 异常情况下的生命周期。是指Activity被系统回收或者由于当前设备的Configuration发生改变从而导致Activity被销毁重建,异常情况下的生命周期的关注点和典型情况略有不同。
典型情况下的生命周期
onCreate:表示Activity正在被创建。
onRestart:表示Activity正在重新启动。
onStart:表示Activity正在被启动,即将开始,这时Activity已经可见,但是还没出现在前台。
onResume:表示Activity已经可见,并且出现在前台并开始活动。
onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。
onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。
onDestroy:表示Activity即将被销毁,这是Activity生命周期中的最后一个回调,可以做一些回收工作和最终的资源释放。
注意点:
1,当用户打开新的Activity或者切换到桌面的时候,回调如下:onPause -> onStop,这里有一种特殊情况,如果新的Activity采用了透明的主题,那么当前Activity不会回调onStop。
2,onStart和onResume、onPause和onStop,有什么实质不同呢。
从Activity是否可见的角度看,onStart和onStop配对,从Activity是否位于前台这个角度,onResume和onPause配对。
3,假设当前Activity为A,如果这时用户打卡一个新的Activity B,那么B的onResume和A的onPause哪个先执行。
先会执行A的onPause后,新的Activity才能启动。官方文档中有这么一句,不能在onPause中做重量级的操作,因为必须onPause执行完成以后,新的Activity才能Resume。
异常情况下的生命周期分析
1,资源相关的系统配置发生改变导致Activity被杀死并重新创建。
比如当前Activity处于竖屏状态,突然横屏了,那么此时系统配置发生了改变,在默认情况下,Activity就会被销毁并且重新创建,拿的资源图片就会不一样,当系统配置发生变化之后,Activity会被销毁,其中onPause、onStop、onDestroy均会被调用,由于Activity是在异常情况下终止的,系统就会调用onSaveInstanceState来保存当前的Activity状态,这个方法是在onStop之前,它和onPause没有既定的时序关系,可能在onPause之前,也可能在onPause之后调用,需要强调下, 这个方法只会在Activity背异常终止的情况下调用,正常情况下系统不会回调这个方法。当Activity重新创建后,系统会调用onRestoreInstanceSate,并且把之前保存的数据恢复回来。
关于保存和恢复View层次结构,系统的工作流程是这样的:首先Activity被意外终止时,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window再委托它上面的顶级容器去保存数据,顶级容器是一个ViewGroup,一般来说它很可能是DecorView。最后顶层容器再去一一通知它的子元素来保存。这是一种典型的委托思想,上层委托下层,父容器委托子元素去处理一件事,这种思想在Android中很常见,比如View的绘制过程,事件分发等等。
总之,系统只有在Activity异常终止的情况下才会调用onSaveInstanceState和onRestoreInstanceSate来存储和恢复数据,其他情况下不会触发这个过程。
2,资源内存不足导致优先级低的Activity被杀死
Activity按照优先级从高到低,可以分为三种。
- 前台Activity—正在和用户交互的Activity,优先级最高
- 可见但非前台Activity—比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互
- 后台Activity—已经被暂停的Activity,比如执行了onStop,优先级最低
当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在的进程,并后续通过onSaveInstanceState和onRestoreInstanceSate来存储和恢复数据,如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死,因此,比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。
Activity的启动模式
Activity的LaunchMode
- standard:标准模式,系统默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。在这个模式下,谁启动了Activity,那么这个Activity就运行在启动它的那个Activity所在栈中。
- singleTop:栈顶复用模式。在这种模式下,如果新的Activity已经位于任务栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法的参数我们可以取出当前的请求信息
- singleTask:栈内复用模式。这是一种单例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会创建实例,和singleTop是一样,系统也会调用onNewIntent。还有一点,就是singleTask有clearTop的效果,会导致栈内已有的Activity全部出栈。
- singleInstance:单实例模式。这是一种加强的singleTask模式,它除了具有singleTask的所有特性以外,还加强了一点,那就是具有此模式的Activity只能单独位于一个任务栈中,比如Activity A是singleInstance模式,当A启动后,系统会为它创建一个新的任务栈,然后A独自在这个新的任务栈中,由于栈内复用的特性,后续均不会创建新的Activity,除非这个独特的任务栈被系统销毁。
如何给Activity指定启动模式,有两种方法,第一种是通过AndroidMenifest.xml
<activity
android:name="com.ryg.chapter_1.SecondActivity"
android:configChanges="screenLayout"
android:label="@string/app_name"
android:launchMode="standard"
android:taskAffinity="com.ryg.task1" />
另外一种情况是通过Intent中设置标志位来为Activity指定启动模式。
Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
这两者是有区别的,首先,在优先级上,第一种方式优先级要高于第一种,当两种同时存在的时候,以第二种方式为准,第一种方式无法直接为Activity设为FLAG_ACTIVITY_CLEAR_TOP标识,而第二种方式无法为Activity指定singleInstance模式。
Activity的Flags
FLAG_ACTIVITY_NEW_TASK:这个标记位的作用是为Activity指定“singleTask”启动模式,其效果和在XML中指定该模式相同。
FLAG_ACTIVITY_SINGLE_TOP:这个标记位的作用是为Activity指定“singleTop”启动模式,其效果和在XML中指定该模式相同。
FLAG_ACTIVITY_CLEAR_TOP:具有次标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈,这个标记位一般会和singleTask启动模式一起出现。如果被启动的Activity的实例已经存在,那么系统就会调用它的onNewIntent
阅读扩展
源于对掌握的Android开发基础点进行整理,罗列下已经总结的文章,从中可以看到技术积累的过程。
1,Android系统简介
2,ProGuard代码混淆
3,讲讲Handler+Looper+MessageQueue关系
4,Android图片加载库理解
5,谈谈Android运行时权限理解
6,EventBus初理解
7,Android 常见工具类
8,对于Fragment的一些理解
9,Android 四大组件之 " Activity "
10,Android 四大组件之" Service "
11,Android 四大组件之“ BroadcastReceiver "
12,Android 四大组件之" ContentProvider "
13,讲讲 Android 事件拦截机制
14,Android 动画的理解
15,Android 生命周期和启动模式
16,Android IPC 机制
17,View 的事件体系
18,View 的工作原理
19,理解 Window 和 WindowManager
20,Activity 启动过程分析
21,Service 启动过程分析
22,Android 性能优化
23,Android 消息机制
24,Android Bitmap相关
25,Android 线程和线程池
26,Android 中的 Drawable 和动画
27,RecylerView 中的装饰者模式
28,Android 触摸事件机制
29,Android 事件机制应用
30,Cordova 框架的一些理解
31,有关 Android 插件化思考
32,开发人员必备技能——单元测试
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)