今天在使用startActivityForResult()方法跳转Activity时,没等跳转到的Activity B执行完成,Activity A就已经执行了OnActvity Result()方法,结果找到问题出在Activity B在Manifest中的launchMode属性设置为singleTask。根据startActivityForResult的文档中的一句话:are launching uses the singleTask launch mode,it will not run in your task and thus you will immediately receive a cancel result。也就是说Activity B不能是单例或单任务启动模式,即launchMode不能这样设置。
由此,我了解了一下Activity的启动模式。
android应用程序都是通过launcher启动,首先来分析launcher这个Activity:launcher是由系统启动(由ActivityManager Service启动,通过发送Intent来启动Launcher),当launcher启动后这个Activity成为Task0,相当于启动一个Task0,launcher是Task0维护的栈中的根元素。
这里注意,当launcher中点击app0启动图标不会在Task0中继续添加,而是会为app0新建一个Task1任务。launcher启动其他Activity都是以new Task的方式启动的。这样没启动一个任务都会新建一个任务(如果任务不存在)。这样多个任务就启动了,点击HOME键的时候会启动launcher,相当于把launcher这个任务从后台移动到前台,这个时候继续点击app1,也就相当于将app1所在的Task1移动到前台,Task0移动到后台。
再来说说Task,简单来说,就是一组以栈的模式聚集在一起的Activity组件集合。新加入的Activity组件,位于栈顶,并仅有在栈顶的Acitivity,才会有机会与用户进行交互。
LaunchMode(启动模式)
1 标准模式
1)从task中启动Activity时,该Activity的新实例总是在当前task中创建
2)每次启动Activity,都会创建该Activity的多个实例
3)一个task中可以存在同一Activity的多个实例
4)一个Activity的多个实例可以出现在多个task栈中
2 singleTop
1)如果Activity未处于栈顶,则其表现与启动模式设置为standard的Activity的表现一致,若处于栈顶,则调用该Activity实例的onNewIntent()方法,将新的intent传递给该实例。
3 singleTask
1)设置为singleTask的Activity,具有全局唯一性,只能创建该Activyt的一个实例
2)如果被启动的Activity的LaunchMode属性被设置为singleTask,已经存在该Activity的实例,则将该实例之上的所有Activity实例释放,将该实例重新带回到栈顶,并调用onNewIntent()方法,将新的intent传递给该实例。
3)在创建设置为singleTask模式的Activity的实例时,如果当前task的taskAffinity与该Activity的taskAffinity一致,则直接在当前task中创建。如果不一致,则在新的任务Task中创建该Activity的实例。
taskAffinity属性:每个Activity都有taskAffinity属性,这个属性指出了他希望进入的Task。
4 singleInstance
1)当创建设置为singleInstance模式的Activity时,总是在新的任务(Task)中创建
2)全局唯一性,只存在该Activity的一个实例
3)该Activity所在的task栈中不可能存在其他的activity