android中对launchMode和task的理解

来源:互联网 发布:怎么在知乎发表文章 编辑:程序博客网 时间:2024/06/06 22:54

网上太多关于launchMode的说法了,好多说法不一致,自己跑demo来验证一下。

standard

准备两个activity:MainActivity和Main2Activity,先不指定MainActivity的launchMode:
这里写图片描述
在oncreate和onResume加上打印:
这里写图片描述

intent到自己:

public void toMainActivity(View view){        Intent intent = new Intent(getApplicationContext(), MainActivity.class);        startActivity(intent);    }

点击intent到自己:
这里写图片描述
下面是打印:
这里写图片描述
这样会产生多个实例,后面新的实例会覆盖之前的activity,点击返回依次出现之前的activity。

没有指定launchMode,其实是standard,特点是会产生多个实例。

singleTop

下面指定为singleTop:
这里写图片描述
intent到自己:
这里写图片描述
不会产生新的实例。
进入其它activity后再启动MainActivity:
这里写图片描述
会产生新的实例。
singleTop模式下,类似standard,但如果当前activity处于栈顶,不会产生新的实例。

singleTask

把MainActivity指定为singleTask:
这里写图片描述
跳转到自身,不会新建实例,只会再次进入onResume;从Main2Activity跳转到MainActivity,会把MainActivity弹出到界面,并且也不会产生新的实例。

singleInstance

下面把Main2Activity指定为singleInstance:
这里写图片描述
从MainActivity跳转到Main2Activity:
这里写图片描述
注意到,之前一直保持不变的taskID变了,就是说singleInstance会把activity放入新的task,在Main2Activity中跳转到自身,仍然不会产生多个实例。

下面把MainActivity指定为singleInstance,从MainActivity到Main2Activity再到MainActivity:
这里写图片描述
结果:
这里写图片描述
MainActivity只有单个实例,并且task510中,只会有MainActivity,Main2Activity会新开一个task。

从MainActivity到Main2Activity回到MainActivity再到Main2Activity:
这里写图片描述
虽然Main2Activity是standard,从MainActivity跳转到它,还是只有一个实例,只有它跳转到自身会产生多个实例:
这里写图片描述
下面再回到MainActivity,进入Main2Activity:
这里写图片描述
回到了最后创建的Main2Activity,下面点击返回,看会不会把这个task中,下面的Main2Activity推到前台:
这里写图片描述
果然,下面的84a9547被推到前台,可以想象,再返回,下面的9e120b9会出来:
这里写图片描述
此时还存在的activity是下面蓝色背景的activity:
这里写图片描述
还剩下两个activity在不同的task中,再返回就只有MainActivity了:
这里写图片描述
再返回,就没有activity,回到桌面了。

可以看出,activity是通过task的方式来管理的,在同一个task内的操作,如intent到自身,或销毁本task内的activity,都只会在当前task内进行操作;当task中没有其它activity了,才会返回到之前新建的task。
singleInstance会优先保证只有一个实例,如果没有,会新开一个task。

比较难以理解的是把MainActivity指定为singleInstance,Main2Activity为standard,从MainActivity到Main2Activity再到MainActivity:
这里写图片描述
从MainActivity intent到Main2Activity intent到MainActivity 再inteng到Main2Activity 并不会产生多个Main2Activity 的实例:
这里写图片描述
第二次intent到Main2Activity 只是回到了上一次产生的实例。这样是否可以理解为:singleInstance让当前task中只有一个activity,并且当产生跨task的操作时,也不会产生重复的实例。
没看过源码,只是猜想。

2017年11月29日补充:
把MainActivity设为standard,SecondActivity为SingleInstance:
这里写图片描述
然后在MainActivity和SecondActivity之间按照下面顺序切换:

  1. 启动Demo,从MainActivity start SecondActivity:
    这里写图片描述
    SecondActivity在新的task中;

  2. 在SecondActivity中start MainActivity:
    这里写图片描述
    因为MainActivity是standard,所以又创建了一个实例;

  3. 按返回:
    这里写图片描述
    这里并没有按照activity的启动顺序回到上一个activity,而是回到了这个task中的上一个activity;
  4. 再按返回:
    这里写图片描述
    回到了SecondActivity,此时已经是另一个task了,并且Demo中只有这个activity了,再点击返回就退出所有activity了。
    这说明android中对activity的操作,默认是在同一个task,比如有两个task,创建和删除activity都会在相同的task来操作activity;当某个task中没有activity了,还要继续删除activity时,才会切换到其它task中去删除activity。

下面又做一次测试:
把MainActivity设为standard,SecondActivity为SingleInstance,反复从MainActivity start SecondActivity,再从SecondActivity start MainActivity ,再从MainActivity start SecondActivity,再从SecondActivity start MainActivity ,反复操作多次:
这里写图片描述
MainActivity 被创建了多个实例,但SecondActivity始终只有一个实例,说明singleInstance和singleTask一样,不会产生多个实例。

下面测试下,两个activity之间的通信会不会受到影响:
把MainActivity设为standard,SecondActivity为SingleInstance,MainActivity使用startActivityForResult启动SecondActivity,在SecondActivity点击button,setResult返回给MainActivity:
这里写图片描述

这里写图片描述

得到的ResultCode是0,就是CANCELED不受影响:
这里写图片描述
setResult为OK:
这里写图片描述
结果为-1,也不受影响:
这里写图片描述
这说明在,至少在android 7.0上,activity在不同task中,使用startActivityForResult是不受影响的。

原创粉丝点击