这里回顾一下,activity的启动相关,如启动模式、任务栈。
一、activity的启动
首先,启动一个activity,有以下几种方式:
1.直接跳转,startActivity(new Intent(A.this,B.class));
activity中启动另一个activity,在intent中可put参数。
Intent intent = new Intent(A.this,B.class);
intent.putExtra("id",id);
startActivity(intent);
2.支持返回结果的跳转,startActivityForResult(intent,REQUEST_CODE);
A启动B,
A中跳转的代码,
int REQUEST_CODE = 1;
startActivityForResult(new Intent(A.this,B.class),REQUEST_CODE);
B中代码,
int RESULT_CODE = 2;
Intent data = new Intent();
setResult(RESULT_CODE,data);//data中可存放需要回传的数据
finish();
A中接收的代码,
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == REQUEST_CODE){
switch(requestCode){
case REQUEST_CODE:
//操作
break;
default:
break;
}
}
}
这里,android本身有提供一些基本的code,在activity的源码中,我们可以看到
/** Standard activity result: operation canceled. */
public static final int RESULT_CANCELED = 0;
/** Standard activity result: operation succeeded. */
public static final int RESULT_OK = -1;
/** Start of user-defined activity results. */
public static final int RESULT_FIRST_USER = 1;
其实,在B中,我们可以直接使用系统所定义好的resultcode,
setResult(RESULT_OK,data);
3.intent隐式跳转
思考这样一个问题:如果,我们需要在依赖的项目中,写跳转,回到主项目,我们改怎么做?(例如,在环信聊天页面,点击扩展了的消息,跳转到主项目的某个Activity)
我们可以使用隐式跳转,从A跳转到B,则A中跳转代码如下,
Intent intent = new Intent("candroid.intent.action.xx");
startActivity(intent);
B在配置文件AndroidManifest.xml中的一些配置,
<activity android:name=".B">
<intent-filter>
<action android:name="android.intent.action.xx" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
二、activity的启动模式
系统默认下,启动一个Activity,放入任务栈,每次按下back键,任务栈中退出一个activity。
android共有如下四种启动模式,
1. standard 标准模式
android默认模式。每次start一个activity,都会去新创建,并且放入任务栈。谁启动的,就在谁所在的任务栈中。
当我们使用ApplicationContext去启动一个standard模式的activity时,会报错:android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
问题原因:由于默认standard模式启动的activity会进入启动它的activity所属的任务栈中去,而ApplicationContext没有任务栈,所以问题就出现了。
解决方法:为代启动的Activity设定一个标记位intent. addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).
2. singleTop 栈顶复用
如果所启动的activity在栈顶,那么,该activity实例会被复用而不会新建,并调用其onNewIntent方法,来接收数据。当然,如果不在栈顶,依然会去新创建一个实例。
onNewIntent调用时机:如果IntentActivity处于任务栈的顶端,也就是说之前打开过的Activity,现在处于onPause、onStop 状态的话,执行顺序为:
C.onPause()
A.onNewIntent()
A.onRestart()
A.onStart()
A.onResume()
C.onStop()
C.onDestroy()
3. singleTask 栈内复用
具有clearTop效果,如果所需要启动的activity在同一栈内,会导致栈内所有在其之上的activity出栈。
4. singleInstance 单实例
单独存在于一个栈中。
三、任务栈
每一个APP都有一个默认的任务栈,其名称(其taskaffinity)为配置文件中的包名。默认情况下,所有启动的activity都按启动顺序放入了这个栈中。
以下内容参考自http://blog.csdn.net/jjmm2009/article/details/50117049
Task,简单的说,就是一组以栈的模式聚集在一起的Activity组件集合。它们有潜在的前后驱关联,新加入的Activity组件,位于栈顶,并仅有在栈顶的Activity,才会有机会与用户进行交互。而当栈顶的Activity完成使命退出的时候,Task会将其退栈,并让下一个将跑到栈顶的Activity来于用户面对面,直至栈中再无更多Activity,Task结束。
比如,启动一个浏览器,在Android中是一个比较沉重的过程,它需要做很多初始化的工作,并且会有不小的内存开销。但与此同时,用浏览器打开一些内容,又是一般应用都会有的一个需求。设想一下,如果同时有十个运行着的应用(就会对应着是多个Task),都需要启动浏览器,这将是一个多么残酷的场面,十个Task栈都堆积着很雷同的浏览器Activity,
是多么华丽的一种浪费啊。于是你会有这样一种设想,浏览器Activity,可不可以作为一个单独的Task而存在,不管是来自那个Task的请求,浏览器的Task,都不会归并过去。这样,虽然浏览器Activity本身需要维系的状态更多了,但整体的开销将大大的减少,这种舍小家为大家的行为,还是很值得歌颂的
以下内容参考自http://blog.csdn.net/liang5630/article/details/41985329/
1.一个应用程序一般都是由多个activity组成的。
2.任务栈(task stack)(别名back stack后退栈) 记录存放用户开启的activity的。
3.一个应用程序一被开启系统就给他分配一个任务栈,当所有的activity都退出的时候,任务栈就清空了。
4.任务栈的id是一个integer的数据类型 自增长的。
5.在android操作系统里面会存在多个任务栈,一个应用程序一个任务栈。
6.桌面应用和一般的应用程序是一样的,任务栈的行为也是一样。
7.默认情况下, 关闭掉一个应用程序,清空了这个应用程序的任务栈。应用程序的进程还会保留。
为什么要引入任务栈的概念:
windows下 可以通过点击任务栏 切换任务
android下 长按小房子 切换任务