大家多少都会遇到这个问题。
而且早在两年前也有人提出解决办法。
http://stackoverflow.com/questions/6356467/activity-stack-ordering-problem-when-launching-application-from-android-app-inst
重现方式:
1.用android系统的installer安装apk,成功后点击提示的dialog打开应用。
2.假设主界面为A,然后从A点击进入B界面。
3.点击home键,将程序置于后台。
4,在launcher上点击该应用,再打开。
预期:应打开显示B。。。。
结果:但结果打开的是A,然后点返回键返回到B了!!我擦泪。
本来想看一下源码这一块是怎么搞得。。。但最近vpn。。。
所以想了一个比较笨的方法。
建一个测试项目,在其主界oncreat的时候,判断其getIntent所有的flags,将其打印出来。。。
private String creatLogStr(int flag, String logTitle) {
int result = getIntent().getFlags() & flag;
return logTitle + " :" + (result == 0 ? false : true) + "\n";
}
顺便打印一下task和activity
taskTv.setText("taskId:" + getTaskId() + "\n activity:" + this.toString());
然后重复整个流程,结果如下图:
1.第一次用installer安装成功,在用其打开时
2.home键回到主界面,再点击icon打开时
发现installer打开时直接用的是FLAG_ACTIVITY_NEW_TASK,而主界面打开用的是FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,但如果按照上述流程,会多出来一个flag,FLAG_ACTIVITY_BROUGHT_TO_FRONT。。。。
FLAG_ACTIVITY_NEW_TASK我不用解释了,大家都常用。。。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED的大概就是启动程序,如果程序已经启动,就把他置到前台即可,没有的话新启动一个。
FLAG_ACTIVITY_BROUGHT_TO_FRONT,api的解释是它是launchMode的singleTask去加的。。。然后也没说什么意思。。。
然后,我自定义了一个start 的app用来打开测试app。
核心代码是这个:
Intent intent = new Intent();
intent = getPackageManager().getLaunchIntentForPackage(
"com.cc.testopenappintent");
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
boolean result = (intent.getFlags() & intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0;
Log.e("startactivity intent", "hase FLAG_ACTIVITY_BROUGHT_TO_FRONT"
+ result);
startActivity(intent);
这样子就会有好几种启动方式来组合。
启动方式:
1.launcher的icon打开
2.installer安装后打开
3.在电脑用adb安装并打开
4.用第三方app 不加任何flag打开
5.用第三方app加上FLAG_ACTIVITY_RESET_TASK_IF_NEEDED打开
经搭配测验,结果如下:
其实这几个打开方式无非都是FLAG_ACTIVITY_NEW_TASK,有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED和无FLAG_ACTIVITY_RESET_TASK_IF_NEEDED。
再有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED打开时,然后用无FLAG_ACTIVITY_RESET_TASK_IF_NEEDED的打开,结果发现。。。多了FLAG_ACTIVITY_BROUGHT_TO_FRONT,而且有重新起了一个主界面。
然后用FLAG_ACTIVITY_NEW_TASK起一个,然后在用有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED的启动。。。结果也一样。。。
略逗比。那解决的办法就很明了了。。
@Override
protected void onCreate(Bundle savedInstanceState) {
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
finish();
return;
}
super.onCreate(savedInstanceState);
}
在主界面的oncreat加上这个。