Activity的启动模式、任务栈以及使用场景

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ae_fring/article/details/79749479
Activity的启动模式、任务栈以及使用场景

目录
  • Activity
  • 生命周期
  • 任务栈
  • 启动模式
  • Intent Flag
  • taskAffinity属性
一、
Activity作为最常用的四大组件之一,肯定都很熟悉其基本用法了。这里就不写介绍了。
二、
生命周期: 官方介绍的Activity生命周期图.。

下面开始讲解:
先提前把Activity的四种启动模式说一下:
manifest 中对应注册Activity下 android:launchMode="standard"
①standard(默认)
②singleTop
③singleTask
④singleInstance
(1)、第一种情况:正常的启动一个Activity
启动:
退出:
(2)打开并按下home键
再重新打开:

(3)在打开FourActivity情况下再打开个Dialog的Activity
DiaLog样式的FiveActivity消失

(4)重新打开按下菜单键(会进到多任务 概览屏幕 的一个界面)
再点击进入
退出
(5)重新打开然后切换成横屏
接着横屏切换回竖屏
当切换成横屏或者竖屏时都会走完Activity的生命周期重新创建一个Activity
但会在 onSaveInstanceState 保存数据在 onRestoreInstanceState 里取数据出来进行操作

ConfigChanges ,用于捕获手机状态的改变。在Activity中添加了android:configChanges属性,在当所指定属性(Configuration Changes)发生改变时,通知程序调用onConfigurationChanged()函数。
对Activity设置 android :configChanges= "orientation|keyboardHidden"

重新打开然后切换成横屏
接着横屏切换回竖屏


三、任务栈
Activity的任务栈和启动模式相关:
一、standard模式:
一、在FourActivity中启动FourActivity:
退出

结论: standard( 标准模式),每次启动都会创建一个新的Activity实例(在不指定启动模式的情况下都是默认以此种方式启动的),覆盖在原有的Activity上,原有的Activity入栈。
二、singleTop模式:
一、在FourActivity中启动FourActivity
退出:

二、 FourActivity中启动FiveActivity--->启动FourActivity
FourActivity-->FiveActivity
FiveActivity-->FourActivity
退出:

结论: singleTop 此种模式下,Activity在启动时会进行判断,如果当前的App的栈顶的Activity即就是将要启动的Activity,那么就不会创建新的实例,直接使用栈顶的实例。

三、singleTask模式:
一、FourActivity中启动FiveActivity--->启动FourActivity
FourActivity-->FiveActivity
FiveActivity-->FourActivity
退出

结论: singleTask 如果是同一个App中启动某个设置了此模式的Activity的话,如果栈中已经存在该Activity的实例,那么就会将该Activity上面的Activity清空,并将此实例放在栈顶。

四、 singleInstance
一、FourActivity-->启动FourActivity
重新打开FourActivity
再次打开FourActivity
退出
二、FourActivity-->FiveActivity-->FourActivity-->FourActivity-->退出
FourActivity-->FiveActivity
FiveActivity-->FourActivity
FourActivity-->FourActivity
退出

结论: singleInstance 这个模式就很好记,以此模式启动的Activity会存放在一个单独的任务栈中,且只会有一个实例。

四、Intent Flag设置启动模式
Intent对象大致包含Component、Action、Category、Data、Type、Extra和Flag这7种属性,其中Intent的Flag属性用于为该Intent添加一些额外的控制旗标,可以通过Intent的addFlags方法为Intent添加控制旗标。
一、跟Activity跳转有关的Flag旗杆(这里说可能比较常用的,其他的码友可以去看下源码解释)
1、 FLAG_ACTIVITY_NEW_TASK
默认启动旗标,该旗标控制创建一个新的Activity实例,该Flag相当于Activity启动模式中的standard。
2 FLAG_ACTIVITY_CLEAR_TOP
清除当前Activity之上的所有实例,该Flag相当于Activity启动模式中的singleTask,例如,一个Activity栈中包含有A、B、C、D ,4个Activity实例,当在Activity D中以该旗标启动Activity B时,此时Activity栈中只包含A、B两个Activity实例。
3、 FLAG_ACTIVITY_SINGLE_TOP
从名字中不难看出该Flag相当于Activity加载模式中的singleTop模式,即原来Activity栈中有A、B、C、D这4个Activity实例,当在Activity D中再次启动Activity D时,Activity栈中依然还是A、B、C、D这4个Activity实例。
4、 FLAG_ACTIVITY_NO_HISTORY
如名字不存在的历史的标志,以该旗标启动的Activity不会保留在Activity栈中,如:Activity栈中有A、B两个Activity实例,当在Activity B中以该旗标启动Activity C,在Activity C中再启动Activity D,此时Activity栈中只有A、B、D三个Activity实例,即Activity C不会保留在Activity栈中。
5、 FLAG_ACTIVITY_REORDER_TO_FRONT
即如果栈中已有该Activity则直接将该Activity带到前台。如:Activity栈中有A、B、C、D四个Activity,如果在Activity D使用该旗标启动Activity C,那么启动后Activity栈中的情形为:A-B-D-C。

五、taskAffinity
taskAffinity 生效时,如已经存在相应名称的任务栈,则不会新建栈,而是在该栈的栈顶建立相应activity;如果没有相应名称的任务栈,就会建立对应名称的新的任务栈。
(setFlags和addFlags的区别是:setFlags会直接将原来的Flag直接替换掉;而addFlags是将参数添加上去。)
而控制activity所属的任务栈。不过只设置这一个属性是不能完成功能的,需要与其它属性相配合。

一、通过配置方式来实现TaskAffinity来实现
使TaskAffinity属性生效,要与其它属性相配合。在配置文件中,需要设置activity的启动模式为singleTask或singleInstance才能生效(其实singleInstance本来就会在新Task中)。

二.通过动态的方式实现TaskAffinity属性
通过上述的配置,可以实现TaskAffinity属性。但是这样每次启动该Activity都会在TaskAffinity指定的栈中启动。有时候可能会希望该activity在特殊情况下才在TaskAffinity指定的栈中启动,大部分时候还是在原有的任务栈中启动,这个时候就需要动态方式来实现TaskAffinity属性。 
在配置文件中,只制定TaskAffinity属性,而不制定launchMode的属性为singleTask。
< activity android:name=".FourActivity" android:taskAffinity="taskName"/>
这样通过正常方式启动该Activity时,该Activity就会在原有任务栈中启动(启动该Activity的任务栈中)。若想在taskAffinity属性生效,需要在启动该Activity时设置Flag为FLAG_ACTIVITY_NEW_TASK。
Intent intent = new Intent(aAvtivity.this, bActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);

六、使用场景
一、当Activity使用singleTop或者SingleTask启动模式时,且要启动的Activity刚好在栈顶。
例如:A时搜索数据的页面 B->搜索结果列表页面。每次都会退到A搜索再回到B->则会多次创建B。所以A放入B中整合时又想让Intent的数据再B中是不行的。因此就出现了 onNewIntent()方法。
官方解释如下:
  • /**
* This is called for activities that set launchMode to "singleTop" in their package or if a client used the
{@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
* flag when calling {@link #startActivity}. In either case, when the
* activity is re-launched while at the top of the activity stack instead
* of a new instance of the activity being started, onNewIntent() will be
* called on the existing instance with the Intent that was used to
* re-launch it.
* <p>An activity will always be paused before receiving a new intent, so
* you can count on {@link #onResume} being called after this method.
* <p>Note that {@link #getIntent} still returns the original Intent. You
* can use {@link #setIntent} to update it to this new Intent.
* @param intent The new intent that was started for the activity.
* @see #getIntent
* @see #setIntent
* @see #onResume
*/
而使用 getIntent 方法获取到的依旧是以前的Intent,可以通过setIntent方法设置新的Intent。方法参数就是新传递的Intent.。又可以再Intent获取数据。

二、App中Activity过多不好管理。
可以针对App的业务场景封装一个AppActivityManager管理类,用于管理Activity,可以在退出App时候销毁所有Activity。

暂且聊到此,有什么不对的欢迎指出。谢谢你的阅读。





猜你喜欢

转载自blog.csdn.net/Ae_fring/article/details/79749479
今日推荐