Activity生命周期
生命周期的五大状态
- 启动状态
- 运行状态
- 暂停状态
- 停止状态
- 销毁状态
七个时期及一些简单介绍如下图:
onStart和onResume,onPause和onStop实质区别
- onStart和onStop的回调针对Activity是否可见
- onResum 和 onPause回调针对Activity是否在前台(如新开启弹窗或者透明主体的Activity时,原Activity处于onPause状态)
- onPause 使用场景:数据储存、停止动画、注销广播等操作
启动Activity方法的生命调度
- 点击跳转一个新的Activity,这个时候Activity会入栈,同时它的生命周期也会从onCreate() 到 onResume开始变换,这个过程是在ActivityStack中完成的,ActivityStack运行在Server进程里的,这个时候Server进程就通过ApplicationThread的代理对象ApplicationThreadProxy向运行在app进程ApplicationThread发送操作请求。
- ApplicationThread接收到操作请求后,因为它是运行在app进程里的其他线程里,所以Application需要通过Handler向主线程ActivityThread发送操作消息。
- 主线程接收到Application发出的消息后,调用主线程ActivityThread执行相应的操作,并回调Activity相应的周期方法。
常见的生命周期调用方法
正常的调用(常识)
- 正常开启 正常关闭 新Activity出现 (可见,不可见) Activity恢复
异常的生命周期调用
-
资源相关的系统配置发生改变 (屏幕切换)
- 会销毁并重新创建(生命周期)
- 数据被onSaveInstanceState保存(onStop之前)成Bunder对象,数据从onRestoreInstanceState中恢复(onStart之后)
(所以可Bunder数据中判断是否是重建的)
- 数据 从Activity委托Window保存,再到ViewGroup 在让子元素保存
-
在onStop时,由于内存资源不够被销毁
- 恢复的手段同上
利用Android的ConfigChanges的属性来避免一些影响
常见orientation(消除横竖屏的影响)、keyboardHidden(键盘隐藏)、locale(消除系统语言变化影响)、screenSize(消除屏幕大小的影响)
对于Activity生命周期无影响,但是会回调onConfigurationChanges()的方法。
补充
- 可以利用清单文件 和 动态的Activity来指定横屏竖屏,避免屏幕切换的影响
-
两个Activity的跳转一定会执行几个方法
- 正常跳转 onPause -> onCreate, onStart,onResume->onStop
- A的onPause,B的onStart和onResume
- onCreate 由于B之前可能在栈中
- onStop B为透明窗口就没有
Activity四种启动模式
标准standard(默认)
特点
-
每次启动 都会创建一个新的Activity实例并将该实例置于栈顶
- 造成退出时需要一直点击,造成用户体验你好
- 可能造成数据冗余,OOM的问题
- ApplicationContext没有任务栈,所以无法使用standard模式,需要指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动是就会自动创建一个新的任务栈(实际就是singleTask模式)
使用场景
正常都是使用这个
栈顶复用 singleTop
特点
若Activity在栈顶就不会重复创建,会调用实例onNewIntent()的方法,可以传值,但是不会调用onCreate()和onStart()方法
使用场景
新闻推送,某新闻App有三条新闻通知,当点入第一条时,启动一个singleTop,当点击第二条时,只需传入Intent即可,不要继续重用。
栈内复用模式 singleTask
特点
- 创建Activity时,会查看所在任务栈是否存在,若不存在则创建,并创建自身实例;若栈存在,则判断自身实例是否存在,存在则调用onNewIntent()方法,且把上面的Activity弹出,若不存在则直接创建即可
使用场景
APP首页
补充
- Activity切换时,会对singTask的栈进行整体调度
单实例模式 singleInstance
特点
加强的singleTask,只能单独地位于一个任务栈中,具有全局唯一性。即若已经创建过实例,就只会栈内复用
使用场景
与程序分离的界面 电话拨号盘界面
各种模式的任务栈
- standad和singleTop使用的任务栈 为Intent的发送者一致
- singleTask的任务栈由TaskAffinity指定(默认为包名)
(TaskAffinity与allowTaskReparenting联用时,可以导致Activity可以在不同程序之间的任务栈进行转移)
- singleInstance的任务栈是新的
指定任务启动模式
-
在AndroidMenifest为Activity指定
- android:launchMode="singleTask"
- 无法设定FLAG_ACTIVITY_CLEAR_TOP
- taskAffinity只能在这里指定
-
在Intent设定标志位
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- 优先级高于前者
- 无法指定singleInstance
Activity的Flags
- FLAG_ACTIVITY_NEW_TASK :singleTask启动模式
- FLAG_ACTIVITY_SINGLE_TOP :singTop启动模式
- FLAG_ACTIVITY_CLEAR_TOP : 再其上方的Activity都要出栈,配合1使用
- Flag_ACTIVITY_EXCLUDE_FROM_RECENTS : 具有此标记的Activity不会出现在历史Activity列表中,XML中是 android:excludeFromRecents = ”true“';
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。