首先,我们常见的由MainActivity跳转到另外一个Main1Acticity的代码:
1 Intent mIntent=new Intent(MainActivity.this, Main1Activity.class); 2 startActivity(mIntent);
一般的情况之下,以上两个Activity实例是放在task同一个栈里面。但是我们通过了解task的栈原理,知道每一个应用都有自己的task标志taskAffinity,不同的activity实例是可以在不同的栈里面运行的,下面介绍一下Intent中常见的几个flags。
1.FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹 配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。
1 Intent mIntent=new Intent(MainActivity.this, Main1Activity.class); 2 mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3 startActivity(mIntent);
2.FLAG_ACTIVITY_CLEAR_TOP:当Intent对象包含这个标记时,如果在栈中发现存在Activity实例,则清空这个实例之上的Activity,使其处于栈顶。例如:我们的FirstActivity跳转到SecondActivity,SecondActivity跳转到ThirdActivity,而ThirdActivity又跳到SecondActivity,那么ThirdActivity实例将被弹出栈,SecondActivity处于栈顶,显示到幕前,栈内只剩下FirstActivity和SecondActivity。这个SecondActivity既可以在onNewIntent()中接收到传来的Intent,也可以把自己销毁之后重新启动来接受这个Intent。在使用默认的“android:launchMode="standard"”启动模式下,如果没有在Intent使用到FLAG_ACTIVITY_SINGLE_TOP标记,那么它将关闭后重建,如果使用了这个FLAG_ACTIVITY_SINGLE_TOP标记,则会使用已存在的实例;对于其他启动模式,无需再使用FLAG_ACTIVITY_SINGLE_TOP,它都将使用已存在的实例,Intent会被传递到这个实例的onNewIntent()中。
1 Intent mIntent=new Intent(MainActivity.this, Main1Activity.class); 2 mIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 3 startActivity(mIntent);
在使用默认的“android:launchMode="standard"”启动模式下,让Activity不用关闭重建
1 Intent mIntent=new Intent(MainActivity.this, Main1Activity.class); 2 mIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP); 3 startActivity(mIntent);
3.FLAG_ACTIVITY_SINGLE_TOP:当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的,直接利用这个实例。
4.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:如果一个Intent中包含此属性,则它转向的那个Activity以及在那个Activity其上的所有Activity都会在task重置时被清除出task。当我们将一个后台的task重新回到前台时,系统会在特定情况下为这个动作附带一个FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,意味着必要时重置task,这时FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET就会生效。经过测试发现,对于一个处于后台的应用,如果在主选单点击应用,这个动作中含有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,长按Home键,然后点击最近记录,这个动作不含FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,所以前者会清除,后者不会。
1 Intent mIntent=new Intent(MainActivity.this, Main1Activity.class); 2 mIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 3 startActivity(mIntent);
5.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:这个标记在以下情况下会生效:1.启动Activity时创建新的task来放置Activity实例;2.已存在的task被放置于前台。系统会根据affinity对指定的task进行重置操作,task会压入某些Activity实例或移除某些Activity实例。我们结合上面的CLEAR_WHEN_TASK_RESET可以加深理解。
1 Intent mIntent=new Intent(MainActivity.this, Main1Activity.class); 2 mIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 3 startActivity(mIntent);