假设我们App的启动界面为A,则在清单文件中应该是这样的:
<activity
android:name=".A"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
然后我们会有B界面,C界面,D界面。。。
假设我们打开了B界面或者C界面或者D界面,除A以外的任意界面都可以,此时按Home键,使App处于后台运行,然后在桌面上找到App的图标并点击打开,我们会发现App的界面显示为A界面,并没有显示我们之前后台运行时的界面,经过打Log发现,除了A界面,其他的界面都会被销毁。如果我们在App后台运行时,长按Home,从最近任务中点开App,则可以回到原来的界面。这就很神奇了。
试了其他应用又不会这样,对比发现是启动模式的问题,lauchMode不设置的话默认为standard,按我以前的理解,standard和singTask的作用是这样的:
按着这个功能解释的话,可以解释一部分问题。当我们从最近任务中恢复app时,可以回到原来的应用,说明系统没有启动app的主界面,而当从桌面的图标点击恢复app时,系统则启动了主界面,由于主界面设置了singleTask,所以主界面上面的所有界面就都会被销毁。这么理解似乎可以解释问题的原因,但是换成standard时又解释不通,换成standard后,从桌面点击app图标,如果系统是调用了startActivity开启主界面的话,则应该会再创建一个新的主界面,主界面会置于栈顶,但是实际运行效果并不是,实际运行的效果点击桌面图标与从最近任务中恢复的效果是一样的。
虽然没搞清楚为什么会这样,解决方案就是把启动模式singleTask换成standard即可。
这个问题之前遇到,当时没有即时记录问题,现在大概记得是什么问题,但是具体操作细节记不清了。
先说一下以前学习singleInstance时的理解:
singleInstance:如果启动的Activity不存在就创建,如果存在就将指定的Activity移动到栈顶(原来它上面的所有Activity不会销毁)
这里少了一个理解,以这个模式开启的Activity将会处于一个新的任务栈中,带来的问题跟上面的差不多,就是后台运行后,我不记得是从最近任务还是从桌面图标中恢复了,会发现回不到之前的界面。
后来工作又开发了一个新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,就是这么简单,这样处理之后,点击桌面图标时就不会导致系统又给我们开启主界面了!