最近有处理一个问题是:WPS office分屏状态下新建一个TXT时会在另一个窗口显示编辑界面。
分析流程:出现这种问题一般都是新建的界面设置了一些特别的属性导致。
通过命令dumpsys window |grep mFocusedWindow 查看新建一个TXT界面对应的Activity是:cn.wps.moffice_eng/cn.wps.moffice.writer.multiactivity.Writer1
通过反编译WPS office apk,查看AndroidManifest.xml文件,Writer1对应的声明为:
通过自己写简单app验证,是由于加了launchMode及taskAffinity属性导致两个Activity属于不同的Task导致。
正好借此机会梳理下android:launchMode与android:taskAffinity之间的关系。
1.android:launchMode
Activity的启动模式,属性值有4个,对应4种不同的启动模式。具体可以参考Activity的四种启动模式
standard:标准模式,默认模式。每次启动Activity时,总是创建一个新的Activity实例,并把这个Activity实例添加到当前的Task中(不会创建新的Task),不管这个Task中是否已经有了一个相同的Activity的实例。
singleTop:Task顶部单例模式,当将要启动的Activity已经位于Task顶部,则不创建新的Activity实例,而是直接使用已有的Activity实例,否则在当前Task中创建新的Activity实例。
singleTask:Task内单例模式,在同一个Task中已经存在了将要创建的Activity的实例,则直接复用,不再新创建Activity实例。即在同一个Task中,只存在同一个Activity的一个实例。分3种情况:
(1)在Task中将要创建的Activity不存在,则创建Activity的实例。
(2)在Task中将要创建的Activity存在,且位于栈顶,则不创建Activity的实例,直接复用。此时与singleTop模式一致
(3)在Task中将要创建的Activity存在,不位于栈顶,则系统把位于该Activity实例之上的所有Activity移出Task,使得目标Activity位于栈顶。
singleInstance:全局单实例模式,无论从哪个Task中启动目标Activity,只会创建一个Activity实例,并且会使用一个新的Task来存放该Activity。
2.android:taskAffinity
Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的依附关系。默认情况下在同一个应用中,启动的Activity都在同一个Task中。
在standard模式下,设置两个Activity的android:taskAffinity不一致,打开这两个Activity,得到TaskId是一样的,即这两个Activity被放置在同一个task中。
在singleTop模式下,设置两个Activity的android:taskAffinity不一致,打开这两个Activity,得到TaskId是一样的,即这两个Activity被放置在同一个task中。
在singleTask模式下,设置两个Activity的android:taskAffinity不一致,打开这两个Activity,得到TaskId是不一样的,即这两个Activity被放置在两个task中。当两个Activity被放置在两个Task中的时候,点击recent键,可以看到此时recent应用中分别显示Activity1和Activity2。设置两个Activity的android:taskAffinity一致(非默认),打开这两个Activity,得到TaskId是不一样的,即这两个Activity被放置在两个task中。设置两个Activity的android:taskAffinity一致(默认的),打开这两个Activity,得到TaskId是一样的。
在singleInstance模式下,设置两个Activity的android:taskAffinity不一致,打开这两个Activity,得到TaskId是不一样的,即这两个Activity被放置在两个task中。当两个Activity被放置在两个Task中的时候,点击recent键,可以看到此时recent应用中分别显示Activity1和Activity2。设置两个Activity的android:taskAffinity一致(非默认),打开这两个Activity,得到TaskId是不一样的,即这两个Activity被放置在两个task中。设置两个Activity的android:taskAffinity一致(默认的),打开这两个Activity,得到TaskId是不一样的。
以上都有进行简单的代码验证,代码太简单,就不贴了~