其他分享
首页 > 其他分享> > Activity2

Activity2

作者:互联网

Activity2

进程模式

在这里插入图片描述
o前台进程
当前进程activity正在和用户进行交互;
当前进程service进程正在和用户进行交互,或者当前service调用了startForground()属于前台进程,或者当前service正在执行生命周期(onCreate(),onStart(),onDestory());
进程持有一个BroadcostReceiver,这个BroadcostReceiver正在执行onReceiver()方法;
o可见进程
进程持有一个activity,这个activity不在前台,处于onPause()状态下,当前覆盖的activity是以dialog形式存在的。
进程有一个service,这个service和一个可见的activity进行绑定。
oservice进程
当前开启startSerice()启动一个服务就可以认为进程是一个服务进程
o后台进程
activity的onStop()被调用,但是onDestory没有被调用,
o空白进程
该进程没有任何运行的数据,且保留在内存空间中,没有被系统killed,属于空进程;这样的进程很容易被杀死。

生命周期

在这里插入图片描述
oonCreate()
代表创建,进行一些初始化的工作,如setContentView加载布局,还有对一些控件进行初始化等
oonStart()
代表启动,这个时候activity已经可见了,但是还没有出现在前台,不能和activity发生交互;onCreate()只在activity创建时执行一次,但是onStart()会在Activity的切换和按HOME键返回桌面然后又切回应用的过程中被多次调用。动画的初始化在onStart()里面做比较好;
oonResume()
代表显示/开始,这个时候Activity已经在前台了,此时的活动一定位于返回栈的栈顶,并且处于运行状态;
oonPause()
这个方法在系统准备去启动或者恢复另一个活动的时候调用。通常在这个方法里面了将一些消耗CPU的资源释放掉,以及保存一些关键数据,但是这个方法执行一定要快,不然会影响到Activity的切换的卡顿。旧Activity的onPause()方法执行完后新的Activity的onResume才会执行。
oonStop()
在活动完全不可见的时候调用,他和onPause的区别在于,如果启动的新活动是一个对话框式的滑动,那么onPause就会被调用,但是onStop()不会;在系统内存不足的时候可能onStop中的操作未完成。
oonDestory()
在活动销毁前调用,调用后活动就会被彻底销毁了。
oonRestart()
表示重新开始,activity在这时可见,当用户按home键切换到桌面后又切回来或者从后一个Activity切回前一个activity就会触发这个方法。
onPause—>onStop–>onRestart–>onStart–>onResume
onPause()和onStop()的区别:onPause可以理解为当前Activity失去焦点,而onStop表示当前Activity不可见。如果启动的新活动是一个对话框式的活动(透明主题),那么onPause会被调用,但是onStop不会。

具体场景

oActivity第一次启动/Activity被系统回收后再次打开:
OnCreate—>onStart—>onResume
oActivity A启动Activity B,以及B回退到A
A启动B
在这里插入图片描述

回退时
在这里插入图片描述

上面A启动B时A的onStop方法在B启动后执行的原因:更快的启动新的活动,提高用户体验;下面B回退到A时onStop和onDestroy在A重启后执行也是同样的道理。
o启动新的Activity切换到桌面时
onPause—>onStop
特殊情况:新的Activity采用了透明主题,当前Activity不会回调onStop。
o再次回到原Activity
OnRestart—>onStart—>OnResume
如果新Activity是透明的,用户再回到原Activity
onPause—>onResume
o用户按下back键返回的时候
onPause—>onStop—>onDestory
o横竖屏切换的时候,整个流程重新来一般就是将Activity销毁再创建,但是如果不希望重新的话,可以设置他的configChages=“orientation”,这个时候会走onConfigurationChanged回掉,而不会走任何其他生命周期回调。
oActivity A 通过 Intent 显式启动了 Activity B,当 B 处于可见状态后,A 是否一定会调用 onStop()?
在这里插入图片描述

不一定,如果Activity B是一个背景透明的Activity(也就是说虽然ActivityB在前台,但是仍然能看到ActivityA),那么就不会执行ActivityA的onStop。这个时候的生命周期:

可能会因为内存不足而直接回收掉(一般情况下,被回收掉的Activity的进程是后台进程。如果当前都属于同一个进程也是前台进程,则不会被回收)。
onCreate和onDestroy对应,代表创建和销毁,但是只会调用一次;onStart和onStop对应,代表Activity的可见和不可见,可能会调用多次;onResume和onPause对应,代表是否在前台,也是可能调用多次

异常情况下的生命周期

异常情况指:
o系统发生改变导致Activity被杀掉重新创建
例如旋转屏幕导致系统配置发生改变,默认情况下Activity会销毁并重新创建,但也可以阻止系统重新创建Activity.
没有设置confidChanges属性是屏幕旋转情况下的生命周期:
运行状态—>onSaveInstanceState()—>onStop()—>onDestory()—>onCreate—>onStart()—>onRestoreInstanceState()—>onResume()
设置了configChanges属性时屏幕旋转情况下的生命周期:
运行状态—>onConfigChanged()
o手机内存不足导致低优先级的Activity被杀掉
Activity优先级划分:
1,前台Activity:正在和用户交互的Activity,优先级最高;
2,可见但是非前台Activity:例如弹出了一个对话框的Activity。
3,后台Activity:已经被暂停的Activity,优先级最低。

重建机制onSaveInstanceState&onRestoreInstanceState

这两个方法只有在Activity异常终止的情况下才会被调用,可以通过这两个方法或者onCreate方法来判断Activity是否被重建了。

什么时候重建?

通常在“系统资源回收”或者“配置发生变化的时候”
系统资源回收:App处于背景模式下,可能因为系统内存不足而被回收。
配置发生变化:屏幕方向变化,系统语言更改等等。

为什么有重建机制?

对于资源回收的情况,保存状态到使用时再恢复,远比后台保留进程所占用的资源小的多。
对于配置变化的情况下,只有重建,才能加载不同的布局。

保护和恢复过程

状态:支撑UI界面显示的临时数据,如EditText的文本,CheckBox的勾选等
在这里插入图片描述
重建机制:在Activity销毁前,将这些状态保存下来,然后再重建Activity的时候,就会将这些状态显示出来。
Activity会通过onSaveInstanceState和onRestoreInstanceState来保存和恢复状态:
onSaveInstanceState执行在onStop之前,但是不确定在onPause之前或者之后
API29开始,这个方法一段会在onStop之后执行。
onRestoreInstanceState在onStart之后。
activity会有两个数据结构专门来保存状态
View States:用于保存view的状态
Instance States:用于存储View States以及开发者在onSaveInstanceState中手动保存activity成员变量。

重建流程

Activity在onSaveInstanceState时,会自动收集View Hiercahy中每一个“实现了状态保存和恢复方法”的view的状态,这些状态数据会在onRestoreInstanceState时回传给每一个view。并且回传时是依据View的id来逐一匹配的。

状态保存和恢复的注意事项

1.为了成功保存状态,要求在view内部实现保存和恢复方法
原生的 View 都有做到;如果是自定义 View,务必记住这一点;如果第三方 View 没做到,可以通过继承其来实现保存和恢复方法。
2.为了成功的恢复状态,需要给View赋予对应的ID
3.如果需要保存Activity的成员变量,需要手动重写onSaveInstanceState 和 onRestoreInstanceState 方法。
重写仅仅是为了额外地保存成员变量。重写方法时,记得要保留基类(super)的实现,Activity 正是在基类中完成 View 状态的保存和恢复。

如何避免因为配置变化的重建

在清单文件中为该 Activity 配置 android:configChanges 属性。
比如属性值 orientation|screenSize 对应着旋转屏幕,locale 对应着语言变化。
如此,在配置发生变化时,不会导致重建,而是走 onConfigurationChanged 回调(只会走onConfigurationChanged,其它生命周期都不会走)

onCreate和onSaveInstanceState方法的区别

onRestoreInstanceState回调则表示其中Bundle对象非空,不用加非空判断,OnCreate需要非空判断;建议使用onRestoreInstanceState.
调用时机
onSaveInstanceState在onStop方法之前调用,但和onPause没有时序关系,onRestoreInstanceState在onStart方法之后。
保存和恢复View层次结构
Activity被异常终止时,会委托Window保存数据,它又会委托顶层容器(DecorView)去保存数据,而它又会遍历子元素依次通知它们保存数据,也就是调用相应的onSaveInstanceState和onRestoreInstanceState方法。

Activity启动模式

在这里插入图片描述

设置方式

在这里插入图片描述

标准模式(standard)

Activity默认的启动模式,如果没有指定启动模式的话,这个Activity就是标准模式。
每次启动的时候都会在Activity栈顶创建一个实例

栈顶复用模式(singleTop)

如果要启动的新的activity已经在任务栈栈顶,就不会再创建新的实例,同时它的 onNewIntent方法就会被回调;如果他不在栈顶,就需要创建新的实例
实例:通知栏中通过通知跳转的Activity,还有就是防止两次点击创建了两个Activity实例。

栈内复用模式(singleTask)

o栈内复用模式single Task(比如浏览器)
每次启动该活动是系统首先会在返回栈中检查是否存在该活动的实例,如果存在则直接使用该实例,并把在这个活动只是的所有活动统统出栈,并回调onNewIntent();如果没有发现就创建一个新的活动实例并加入任务栈顶。
应用:大多数APP的主页面Activity

单实例模式(singleinstance)

新启动的Activity会单独放在一个新创建的任务栈中。
应用:来电或者闹钟页面

正常情况下如果某个Activity的启动模式为singleTask或singleTop,在第一次启动这个Activity的时候,会在栈中创建一个新的实例,也就是会调用 onCreate()→onStart()→onResume();如果栈中(singleTop对应的是栈顶)已经有了这个Activity的实例,则会调用:onNewIntent()→onResart()→onStart()→onResume()

onNewIntent陷阱

在onNewIntent()中调用getIntent(),始终只会获取最开始的那个Intent对象。但我们可以在其中调用setIntent()将Intent对象更新。
也就是下面的写法在每次才会拿到最新的Intent:
在这里插入图片描述
但是onNewIntent里面会有一个陷阱,就是我们在onNewIntent调用getIntent的时候,会发现不管调用几次onNewIntent方法,得到的intent都是最初的那个intent。这是因为我们在后面调用onNewIntent的时候没有通过setIntent(intent)方法将新的intent给设置到当前Activity上去,

taskAffinity

每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于包名。
singleTask和taskAffinity配合使用,指定启动的Activity加入到哪个栈中;

为Activity指定启动模式

在清单文件中为Activity指定launchMode属性
在Intent中设置标记位。也就是给startActivity中传入的intent对象通过addFlags方法设置;
第一种无法直接位Activity设置FLAG_ACTIVITY_CLEAR_TOP标识;第二种无法为Activity指定singleInstance。

Activity常用的Flags

FLAG_ACTIVITY_NEW_TASK,近似于 singleTask 模式。当在清单中为 Activity 设置 taskAffinity 属性时,能跳转到指定任务(若先前不存在该任务,则先创建该任务)。该 FLAG 通常用于从非 Activity 的环境下启动 Activity(这么设计,是为了给 Activity 一个容身之处)。
FLAG_ACTIVITY_SINGLE_TOP ,对应着 singleTop 模式。
FLAG_ACTIVITY_CLEAR_TOP,近似于 singleTask 模式。当该 Activity 已存在于任务中,该 Activity 和其上的 Activity 都会出栈,并且该 Activity 会被重新创建和入栈。
FLAG_ACTIVITY_NO_HISTORY,被指定的 Activity 在跳转到其他 Activity 后,将从任务中移除。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,被指定的 Activity 不出现在 “最近应用” 列表中。
所以 即使 FLAG_ACTIVITY_NEW_TASK 与 FLAG_ACTIVITY_CLEAR_TOP 共同使用,其效果也并不完全等同于 singleTask 模式。在于,当栈中存在该 Activity 的实例,而再次启动该 Activity 的实例时,会让已存在的该 Activity 实例及其上的 Activity 全部出栈,然后将新建的该 Activity 实例入栈。而非 SingleTask 的走 onNewIntent。

启动模式和Flags的区别

启动模式和 FLAG 的区别主要在于,前者是固定的,写死在xml文件中;
后者是可组合的,比较灵活。
例如:当你多数场景下不合适使用 SingleTask,但个别场景又需要它的这种清空栈中上方 Activity 的特性,那么此时你就选用 singleTop模式 + clearTop FLAG 的组合,如此,在清单中你配置的是 singleTop,仅在你需要清空效果的场景下,在代码中动态附加 FLAG 来组合使用。

优先级低的Activity在内存不足时被回收之后怎么做可以恢复到被销毁前的状态?

1.通过重建机制。view之类的系统会为我们做好重建,我们需要做的主要就是一个Activity的成员变量,这些就要我们重写onSavaInstanceState去保存,然后在onRestoreInstanceState或者onCreate(onCreate中需要判空)里面去恢复。
2.Activity之间传递数据尽量以Intent传递,因为系统维护的task和返回栈帮我们处理了Intent的保存和恢复。所以当我们优先级低的APP进程被销毁时,再回到这个Activity,虽然Activity仍然会重建,但是可以将Intent中的数据恢复。
 
activity和进程的回收和恢复状态
https://www.jianshu.com/p/72ccb08e7f34

标签:调用,Activity2,启动,Activity,onStop,activity,进程
来源: https://blog.csdn.net/qq_43775976/article/details/114640130