Launcher mode杂记

来源:互联网 发布:亚马逊数据库主从 编辑:程序博客网 时间:2024/06/07 07:08

Android对Launcher mode有专门的介绍,但是有些细节的地方可能并没有描述的很详细,先对四种launcher mode,做一个介绍:

  主要分析下singleTask和singleInstance  第一:设置了"singleTask"启动模式的Activity的特点:     1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的任务存在;如                果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。    2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。对于TASK的管理一直很迷糊,情况居多,但是我感觉只要抓住几个规则,不管怎么变,都能慢慢分析出来,算是个人的一些理解,不一定完全对,但是的结果还是符合要求,launcher mode分为四类,主要表达了2个意思,要不要创建新的实例,要不要启动新的task,要不要创建新的实例很好理解,要不要创建TASK,就得看情况了。 规则一:如果Acitivity没有设置taskAffinity,则默认为包名,其实就是一个字符串而已嘛,没那么神秘,相当于一个TAG。 规则二:  要不要启动一个实例都很好理解,主要分析下要不要启动task:那到底要不要启动一个新的task呢,这个完全是存不存在FLAG_ACTIVITY_NEW_TASK标志决定的,没有那是铁定不会启动新任务的,也就是说哪怕你设置了taskAffinity为其他值都没用,如果设置了那就要看,将要启动Activity的taskAffinity,系统中是否存在,存在则不启动新的task,并且把将要启动的Activity放到和调用者相同的task中去,否则启动新的task。  规则三:设置为singleTask的Activity,如果谁想启动这样一个Activity,相当于调用者,默认设置了FLAG_ACTIVITY_NEW_TASK,那很显然,到底会不会启动一个新的task套用第一和第二个规则。注意: 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。  规则四:设置为singleInstance的Activity,如果谁想启动这样一个Activity,相当于调用者,默认设置了FLAG_ACTIVITY_NEW_TASK,并且设置了一个不同于调用者的taskAffinity,那很显然,到底会不会启动一个新的task,同样套用第一和第二个规则。事实证明,设置为singleInstance的Activity,整个task必须,有且只有一个它,尼玛!! 那很明显,由它启动别的Activity,同样会默认设置为FLAG_ACTIVITY_NEW_TASK的效果,要不要启动新的task,同样参考第一,第二规则。 规则五:点击对桌面的图标,如果是第一次启动程序,会创建一个新的task,如果是已经启动过的程序,再次点击图标,就会把此程序根Activity所在的task,推入前台,这点需要注意,举个例子说明,在一个程序中有是三个Activity,A,B,C,其中B的launcher mode 为singleTask,并且B的taskAffinity和A也不相同,当A-》B-》C,B C是在同一个task中,A在另外一个Task中,但是A是根Activity,此时按Home键,再点击图标,会发现此时只显示A,很多人总会错误的感觉,应该是C在最上面,问题是B C和A不在同一个task当中。如果你想看到B C 你可以长按Home键去查看。规则六:task中的Activity都是作为一个整体,移至前台或者后台。规则七:默认的launch mode的task id 和调用者保持一致。

一个网上很常见的问题:Android应用第一次安装成功点击“打开”后Home键切出应用后再点击桌面图标返回导致应用重启问题

最近项目中遇到一个问题,用户第一次安装应用在系统的安装器安装完成界面有“完成”和“打开”两个按钮。

  当用户点击“打开”按钮进入用户注册页面进行手机号验证码发送和验证码输入等操作界面,若此时用户点击Home键切出应用到桌面,再从桌面点击应用程序图标试图切回应用完成验证码输入等操作时,应用重新走了欢迎页等步骤,此时之前从系统的安装完成界面点击打开启动的应用其实还在后面运行。  然而当用户“完全退出”应用,或者在安装完成界面直接点击“完成”按钮再从桌面启动,或者此应用之前是存在的“覆盖安装”后点击“打开”按钮都是不会导致应用程序“多次启动”的。  经过查找也试过很多种方法,设置activity的launchMode等都不能解决此问题,废话不多说,上解决办法。  其实原因很简单,利用程序安装器打开程序,启动的Intent是没有带Category,而我们自己打开程序是带了Category,所以只需要在配置Intent.ACTION_MAIN的Activity判断下有无Category。然后放到通知栏的时候要更具有无Category 来生成启动的Intent。

if((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0){
finish();
return;
}

官方不推荐我们去更改这些launcher mode,有些场景必须用,设置了以后一定要经过严格的测试。在Activity有个函数moveTaskToBack(nonRoot),是可以用来移动Activity所在的task进入后台。里面的参数如果为true,表示哪怕这个Activty不是根activity,也移动至后台,否则。。。 发现一个问题,当系统配置产生变化时候,例如语言改变 横竖屏,就算Activity设置了launch mode为:singleTask或者singleInstance,Activity还是会重新创建,创了的新的Acitivty,之前配置的singleTask或者singleInstance 任然有效

        假设程序中有A B两个Activity,包名为:com.demo  ,其中B设置为singleTask,A为root activity,此时先启动A,如果A要想启动B,系统就会去获取B的taskAffinity值,由于我们A,B都没设置过,所以默认为包名com.demo,启动A的时候,已经创建了一个名为com.demo的task,刚好B的taskAffinity也是com.demo,那么B直接就丢到A的task中去。

1.点击对桌面的图标,如果是第一次启动程序,会创建一个新的task,如果是已经启动过的程序,再次点击图标,就会把此程序根Activity所在的task,推入前台,这点需要注意,举个例子说明,在一个程序中有是三个Activity,A,B,C,其中B的launcher mode 为singleTask,并且B的taskAffinity和A也不相同,当A-》B-》C,B C是在同一个task中,A在另外一个Task中,但是A是根Activity,此时按Home键,再点击图标,会发现此时只显示A,很多人总会错误的感觉,应该是C在最上面,问题是B C和A不在同一个task当中。如果你想看到B C 你可以长按Home键去查看。

2.程序中有A B C 三个acircity,A为根 B的launcher mode为 singleInstaance,此时A-》B-》C,A C在会在同一个task当中,B在另外一个task中,并且有只有且一个实例。 如果为A也设置一个taskAffinity,B C的taskAffinity为默认,再来实验 A-》B-C,会发现三个activity分别在三个不同的task,也就是说当B设置为singleInstaance之后,由B启动的Activity相当于,给Intent设置了FLAG_ACTIVITY_NEW_TASK标签,那么系统会去查找有没有和B默认taskAffinity相同的task。如果有,就把B放进那个task,没有则创建一个新的task。

1 0
原创粉丝点击