android中singleTask的home键的问题

在Android设计中遇到这样一个问题:

Activity A,在中设置它的一个为

AndroidManifest.xml代码

<intent-filter>  
    <action android:name="android.intent.action.MAIN" />  
 <category android:name="android.intent.category.LAUNCHER" />  
intent-filter>
  A的launchMode为“singleTask”。

  Activity B,设置launchMode为“standard”。

  这样,A作为启动应用的入口Activity;在A中进行某个操作可以跳转到B。

  如果此时,点击‘Home’键返回到Home Screen后,再次点击应用图标进入应用,出现的界面为A,而非B。通过一些测试,发现,在重新进入应用时,在Back stack中,位于A之上的其他Activity均被销毁了。

开发的时候,由于用到了singleTask用法不当,造成了一些不必要的麻烦,现总结如下:
现有Activity:A,B,C,D;启动顺序是A->B->C->D,其中,B是singleTask的。
A到B后,A finish掉;B到C后,B不 finish; C到D后,C不 finish;在D启动B,就可以一下子将C、D kill掉,只保留B。但是,
这个时候你从B退出(整个程序退出了),长按Home键启动,进来的第一个是B,而不是A,这就已经不对了; 而且, 刚才就算你不退出,从B再进到C,按Home,再长按Home进入,回来的是B而不是C。

解决方案如下:

将singleTask改成singleTop。
这样以来,刚才从D启动B的时候,就要用intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
也就是说,singleTask会自动执行clear top, 而singleTop需要手动;而从Home键启动,如果是singleTask的话就自动clear top了,所以到不了想要到的Activity。
这样就解决了问题,但是上面的说法是个人的理解。

Activity有四种加载模式:

standard 
标准启动模式,也是activity的默认启动模式。在这种模式下启动的activity可以被多次实例化,即在同一个任务中可以存在多个activity的实例,每个实例都会处理一个Intent对象。如果Activity A的启动模式为standard,并且A已经启动,在A中再次启动Activity A,即调用startActivity(new Intent(this,A.class)),会在A的上面再次启动一个A的实例,即当前的桟中的状态为A-->A。


singleTop
接下来就是singleTop模式。它的表现几乎和standard模式一模一样,一个singleTop Activity 的实例可以无限多,唯一的区别是如果在栈顶已经有一个相同类型的Activity实例,Intent不会再创建一个Activity,而是通过onNewIntent()被发送到现有的Activity。

singleTask
这种模式和standard以及singleTop有很大不同。singleTask模式的Activity只允许在系统中有一个实例。如果系统中已经有了一个实例,持有这个实例的任务将移动到顶部,同时intent将被通过onNewIntent()发送。如果没有,则会创建一个新的Activity并置放在合适的任务中。

singleInstance
这个模式非常接近于singleTask,系统中只允许一个Activity的实例存在。区别在于持有这个Activity的任务中只能有一个Activity:即这个单例本身。

设置的位置在AndroidManifest.xml文件中activity元素的Android:launchMode属性:

<activity android:name="ActB" android:launchMode ="singleTask">activity>

Intent Flags

除了在AndroidManifest.xml中直接设置launch mode,我们还可以通过叫做 Intent Flags的东西设置更多的行为,比如:

Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

Task

Task是Android Framework中的一个概念,Task是由一系列相关的Activity组成的,是一组相关Activity的集合。Task是以栈的形式来管理的。

我们在操作软件的过程中,一定会涉及界面的跳转。其实在对界面进行跳转时,Android Framework既能在同一个任务中对Activity进行调度,也能以Task为单位进行整体调度。在启动模式为standard或singleTop时,一般是在同一个任务中对Activity进行调度,而在启动模式为singleTask或singleInstance是,一般会对Task进行整体调度。

对Task进行整体调度包括以下操作:

  1. 按Home键,将之前的任务切换到后台
  2. 长按Home键,会显示出最近执行过的任务列表
  3. 在Launcher或HomeScreen点击app图标,开启一个新任务,或者是将已有的任务调度到前台
  4. 启动singleTask模式的Activity时,会在系统中搜寻是否已经存在一个合适的任务,若存在,则会将这个任务调度到前台以重用这个任务。如果这个任务中已经存在一个要启动的Activity的实例,则清除这个实例之上的所有Activity,将这个实例显示给用户。如果这个已存在的任务中不存在一个要启动的Activity的实例,则在这个任务的顶端启动一个实例。若这个任务不存在,则会启动一个新的任务,在这个新的任务中启动这个singleTask模式的Activity的一个实例
  5. 启动singleInstance的Activity时,会在系统中搜寻是否已经存在一个这个Activity的实例,如果存在,会将这个实例所在的任务调度到前台,重用这个Activity的实例(该任务中只有这一个Activity),如果不存在,会开启一个新任务,并在这个新任务中启动这个singleInstance模式的Activity的一个实例。

参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0520/2897.html
http://blog.csdn.net/zhangjg_blog/article/details/10923643

你可能感兴趣的:(Android)