Activity的启动模式
启动模式允许开发者定义一个activity的新实例如何与当前的Task关联。可以定义使用俩种方法来定义。
当在manifest文件中声明activity时,可以指定这个activity开启时如何与当前task关联。
标签的launchMode属性可以设置为四种不同的模式: android:launchMode=“singleTask”
“standard”(默认模式)
“singleTop”
“singleTask”
“singleInstance”
这几种模式的区别体现以下四点上:
1)当这个activity被激活的时候,会放入哪个任务栈。
对于“standard”和“singleTop”模式,这个新被激活的activity会放入和之前的activity相同的任务栈中――除非Intent对象包含FLAG_ACTIVITY_NEW_TASK标志。
“singleTask”并不会每次都新启动一个task。如果已经存在一个task与新activity亲和度(taskAffinity)一样,则activity将启动到该task。如果不是,才启动一个新task。同一个application里面,每个activity的taskAffinity默认都是一样的。
“singleInstance”模式则表示这个新被激活的activity会重新开启一个任务栈,并作为这个新的任务栈的唯一的activity。
2)是否可以存在这个activity类型的多个实例。
对于“standard”和“singleTop”模式,可以有多个实例,并且这些实例可以属于不同的任务栈,每个任务栈也可以包含有这个activity类型的多个实例。
“singleTop"要求如果创建intent的时候栈顶已经有要创建 的Activity的实例,则将intent发送给该实例,而不发送给新的实例。
“singleTask”和”singleInstance”则限制只生成一个实例。
3)包含此activity的任务栈是否可以包含其它的activity。
“singleInstance”模式表示包含此activity的任务栈不可以包含其它的activity。若此activity启动了另一个activity组件,那么无论那个activity组件的启动模式是什么或是Intent对象中是否包含了FLAG_ACTIVITY_NEW_TASK标志,它都会被放入另外的任务栈。在其它方面“singleInstance”模式和“singleTask”模式是一样的。
其余三种启动模式则允许包含此activity的任务栈包含其它的activity。
4)是否每次都生成新实例
对于默认的“standard”模式,每当响应一个Intent对象,都会创建一个这种activity类型的新的实例。即每一个activity实例处理一个intent。
“singleInstance”是其所在栈的唯一activity,它会每次都被重用。
注意:
当已经存在的activity实例处理新的intent时候,会调用onNewIntent()方法
当开启一个activity时,可以通过在intent中包含标志来修改activity的默认的与当前task的关联,然后将该intent传递给startActivity().可以修改的默认的标志为:
FLAG_ACTIVITY_NEW_TASK
在一个新的task中开启一个activity。如果包含该activity的task已经运行,该task就回到前台,activity通过onNewIntent()接受处理该intent。
这是与"singleTask"登录模式相同的行为。
FLAG_ACTIVITY_SINGLE_TOP
如果要被开启的activity是当前的activity(在返回栈的顶部),已经存在的实例通过onNewIntent()接收一个调用,然后处理该intent,而非重新创建一个新的实例。
这与"singleTop"登录模式有相同的行为。
FLAG_ACTIVITY_CLEAR_TOP
如果要被开启的activity已经在当前的task中运行,系统不会生成该activity的一个新的实例,在该栈顶部的所有其他的activity会被销毁,这个intent通过 onNewIntent()被传递给该重新运行的activity的实例(现在在栈顶部)。
manifest中没有相对应的属性。
标题"standard"时,一个新的实例总是被创建
区别
FLAG_ACTIVITY_CLEAR_TOP经常和FLAG_ACTIVITY_NEW_TASK一起使用.当一起使用时,这些标志可以确定一个存在的activity在另一个task中的位置,并且将其放置于可以响应intent的位置(FLAG_ACTIVITY_NEW_TASK确定该activity,然后FLAG_ACTIVITY_CLEAR_TOP销毁顶部其他的activity)。
当一个应用中的Activity供多种方式调用启动,但是希望任务栈中只有一个Activity实例。这样就需要将这个Activity launchMode设置为singleTask。第一次打开会执行onCreate–onStart–onResume,之后如果该Activity没有被destroy,重新打开执行onNewIntent–onRestart–onStart–onResume。
当调用到onNewIntent(intent)的时候,需要在onNewIntent()中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。
activityB 中药跳转ActivityA 中需要
Intent intent = new Intent(SearchActivity.this, MainActivity.class);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Constants.MAINACTIVITYTAG , Constants.FRAGMENTHOMERTAG);
startActivity(intent);
在当前ActivityA 重写onNewIntent 注意要写 **setIntent(intent);**返回的意图。这是一个
*指指明的意图;它不会复制它。获取的Tag值来切换你的ViewPager页面
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
mTag = getIntent().getIntExtra(Constants.MAINACTIVITYTAG, Constants.FRAGMENTHOMERTAG);
Log.e(TAG, "getIntent获取到的上一个intent传值,type=" + mTag);
mainBind.homeViewPager.setCurrentItem(mTag);
}
是不是很简单