Android启动页重复启动
[toc]
1.问题描述
在做项目的时候,发现自己做的App在运行过程中,点击Home键或者Back键回到桌面时,这个时候再点击App启动图标,会再显示一遍启动页(SplashActivity),然后进入到App主界面(HomeActivity)。但实际上我想要的效果是和其他App一致的,就是在App没有被结束掉,然后点击启动图标会进入到退出前的显示界面。流程图大概如下所示。
- 项目中的效果
graph LR
A[HomeActivity] --> B[点击Home/Back键回到桌面] --> C[点击App启动图标] --> D[SplashActivity] --> E[HomeActivity]
- 实际想要的效果
graph LR
A[HomeActivity] --> B[点击Home/Back键回到桌面] --> C[点击App启动图标] --> D[HomeActivity]
2.核心原因
在桌面点击App启动图标的时候,首先是会启动SpalshActivity的,因为SplashActivity被设置成了启动的Actively。
点击Back键后,如果没有重写onBackPressed方法,Activity就会被Finish掉,在HomeActivity这个界面,点击Back键就会退出应用,所以再从桌面点击App启动图标,App会重新启动。
点击Home键后,当前的Activity不会被Finish掉,会调用onPause和onStop方法。
在项目中,SplashActivity的launchMode设置的是standard,HomeActivity的launchMode设置的是SingleTask。点Home键回到桌面后,这个时候点击App启动图标,实际上是启动了SplashActicvity,一般在显示完启动页之后通常会Finish掉,也就是会从任务栈中移除。显示完启动页后进入到HomeActivity,由于之前该应用的任务栈中还存在HomeActivity,而HomeActivity的lanuchMode是SingleTask,也就是会将任务栈中其他的Activity给移除掉。
3.解决步骤
知道了几个关键点之后,逐一解决这些问题。
-
是否需要显示SplashActivity
实际上,如果当前App的任务栈中不为空,我们是希望SplashActivity不显示的,那就在SpalshActivity显示之前Finish掉就好了,加入如下代码。
class SplashActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (!this.isTaskRoot) { if (intent != null) { val action = intent.action if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN == action) { finish() return } } } } }
首先是判断当前Actitvity是否在栈顶,如果是,表示第一次启动,否则表示被启动过。在finish方法后加上return是为了避免执行SplashActivity后续的操作,比如获取配置信息或者其他,具体需要看项目的需求。
-
重写HomeActivity中的onBackPressed方法
在HomeActivity中加入如下代码。
class HomeActivity : AppCompatActivity() { override fun onBackPressed() { moveTaskToBack(true) } }
moveTaskToBack()
方法表示将该Activity的任务移到任务栈的后面(此处解释有点不清楚,需要进一步了解),也就是不会finish掉该Activity。
4.总结
其实解决该问题最重要的就是两点,是否显示SplshActivity以及点击Back键不结束掉Activity,解决了这两个问题基本上就完成了,还有重要的一点是设置Activity的launchMode。
<activity
android:name=".ui.activity.HomeActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<activity
android:name=".ui.activity.SplashActivity"
android:screenOrientation="portrait"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
网友评论