关于Activity的4种启动模式是老生常谈的一个问题,Activity的启动模式是研究 任务栈/回调栈内Activity的存在状态,这4种启动模式分别是:
standard (默认)
傻瓜式的,每调用一次startActivity(MainActivity.class),就会创建一个完全新的Activity对象,然后压倒栈中singleTop(浏览器书签)
如果当前栈顶已经是MainActivity,还依然启动MainActivity,则不会启动新的对象的。保证栈顶的Activity只能一个.singleTask(app的主界面 浏览器)
保证一个任务栈中只能有一份MainActivity,当然可以有其他Activity。如果其他Activity将其覆盖住了,再次去启动MainActivity的时候,系统会杀死MainActivity上面所有的其他Activity。singleInstance(很少用,手机桌面)
保证一个Activity独享一个任务栈。如果启动其他Activity了,其他Activity被放到另外一个新的任务栈中。不管有几个任务栈,MainActivity只能有一份单例对象。
其他Activity的栈如果不在顶部,就把栈换个位置
最近项目中碰到这样一个bug:
主界面存在4个fragment,通过fragmenttabhost进行界面的切换,用户在第四个界面:我的界面中重置密码,因为重置密码功能是独立封装在项目的库工程中的,在退出app登录后并不能控制主界面同时销毁,因此在用户重新登录到主界面后,显示的不是主界面默认第一个界面,而是第四个我的界面.
这个bug产生的原因就是因为主界面设置的launchmode = singletask,一个任务栈中只存在一份单一的HomeActivity,只要HomeActivity不销毁,永远会用原来栈中的Activity进行显示.
为解决这个bug,我们需要用到一个很重要的方法 onNewIntent()
如果当前Activity的启动模式是SingleTop或者singleTask,当再次启动这个Activity的时候,如果该Activity没有创建新的对象,那么其onNewIntent()方法就会被调用,用于接收新的Intent
在onNewIntent中调用fragmenttabhost的setCurrentTab()方法,设置到第一个默认的 fragment即可
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
tabHost.setCurrentTab(0);
}