Activity启动模式设置为singleTask和singleInstance的问题

1、singleTask问题

假设我们App的启动界面为A,则在清单文件中应该是这样的:

		
			
				
				
			
		

然后我们会有B界面,C界面,D界面。。。

假设我们打开了B界面或者C界面或者D界面,除A以外的任意界面都可以,此时按Home键,使App处于后台运行,然后在桌面上找到App的图标并点击打开,我们会发现App的界面显示为A界面,并没有显示我们之前后台运行时的界面,经过打Log发现,除了A界面,其他的界面都会被销毁。如果我们在App后台运行时,长按Home,从最近任务中点开App,则可以回到原来的界面。这就很神奇了。

试了其他应用又不会这样,对比发现是启动模式的问题,lauchMode不设置的话默认为standard,按我以前的理解,standard和singTask的作用是这样的:

  • standard:每次调用startActivity()启动时都会创建一个新的Activity放在栈顶(原来的Activity不会销毁)
  • singleTask:如果启动的Activity不存在就创建,如果存在直接跳转到指定的Activity所在位置(即把它上面的所有Activity销毁掉)

按着这个功能解释的话,可以解释一部分问题。当我们从最近任务中恢复app时,可以回到原来的应用,说明系统没有启动app的主界面,而当从桌面的图标点击恢复app时,系统则启动了主界面,由于主界面设置了singleTask,所以主界面上面的所有界面就都会被销毁。这么理解似乎可以解释问题的原因,但是换成standard时又解释不通,换成standard后,从桌面点击app图标,如果系统是调用了startActivity开启主界面的话,则应该会再创建一个新的主界面,主界面会置于栈顶,但是实际运行效果并不是,实际运行的效果点击桌面图标与从最近任务中恢复的效果是一样的。

虽然没搞清楚为什么会这样,解决方案就是把启动模式singleTask换成standard即可。

2、singleInstance问题

这个问题之前遇到,当时没有即时记录问题,现在大概记得是什么问题,但是具体操作细节记不清了。

先说一下以前学习singleInstance时的理解:
singleInstance:如果启动的Activity不存在就创建,如果存在就将指定的Activity移动到栈顶(原来它上面的所有Activity不会销毁)
这里少了一个理解,以这个模式开启的Activity将会处于一个新的任务栈中,带来的问题跟上面的差不多,就是后台运行后,我不记得是从最近任务还是从桌面图标中恢复了,会发现回不到之前的界面。

3、总结

  1. App的启动界面不要设置为singleTask,否则会导致后台运行后每次从桌面点击恢复时都回到启动面的问题。App中的非启动界面可以设置为singleTask,不会导致后台运行后回不到之前界面的问题。
  2. signleInstance导致多个任务栈,后台运行后回不到之前界面的问题,那什么时候用singleInstance呢,等我有时间了再来研究一下,现在我们知道它会带来什么问题也算是有所收获了。

后续

后来工作又开发了一个新App,有一个主界面,程序一启动就先打开主界面,而且主界面是一直存在不销毁的,这样的话,这个主界面的laucherMode使用SingleTask再合适不过了,但是他又会导致我们上面说的问题。

后来想出了一个解决办法,新建一个空的Activity,启动模式为standard,这个Activity一启动就开启我们的主界面,并结束它自己,代码如下:

<activity
	android:name=".module.LauncherActivity"
	android:screenOrientation="portrait"
	tools:ignore="LockedOrientationActivity"
	android:theme="@android:style/Theme.NoDisplay">
	<intent-filter>
		<action android:name="android.intent.action.MAIN" />
		<category android:name="android.intent.category.LAUNCHER" />
	</intent-filter>
</activity>
class LauncherActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        startActivity<MainActivity>()
        finish()
    }
}

OK,就是这么简单,这样处理之后,点击桌面图标时就不会导致系统又给我们开启主界面了!

你可能感兴趣的:(android)