业务要求:FM播放页、主播主页、栏目详情页可以依托播放页循环点击(如:播放页——主播主页——播放页——栏目详情页)。但返回这三个页面都只保留一个,再回到主页。
采坑日常:
1、启动模式:
A、singleTask: 一开始脑子第一反应就是用启动模式来实现,先想到singleTask。但是他会移除他之上的所有栈。ActivityA→ActivityB→ActicityC→ActivityA(三个都是singleTask模式),系统会先从内部开始把ActivityA与ActicityC之间的Acticity全部结束onDestroy。然后暂停ActicityC,调用ActivityA的onNewIntent->onRestart->onStart->onResume然后再停止并结束ActicityC。所以多次循环后,就不会三个界面都有一个让你去返回了。就不符合我们的业务要求了。
B、singleInstance: 后来想想用singleInstance,他是单一实例,具备所有singleTask的特点,唯一不同的是,它是存在于另一个任务栈中。然后ActivityA->ActivityB->ActivityC→ActivityA(三个都是singleInstance模式),发现返回都正常,以为弄好了。然后Home键,应用退到后台,再次打开的时候发现,居然回到了主页。这是因为当重新启动的时候,系统会先去找主栈(我是这么叫的)里的activity,也就是APP中LAUNCHER的activity所处在的栈。查看是否有存在的activity。没有的话则会重新启动LAUNCHER。这就很不符合我们的业务需要了。有解决办法吗?其实不是没有,但是我想到解决办法实在是自己都不愿意用。所以果断放弃了。
2、既然正常的系统的模式无法满足我的需要,我就在想,该怎么办呢?后来想了下,干脆自己来维护好了,反正就三个页面。所以就自己写了个栈。
public class FMActivityStack {
private static Stack<Activity> stack;
private FMActivityStack() {
stack = new Stack<>();
}
// 当前Activity推入栈中
public static void pushActivity(Activity activity) {
if (stack == null) {
stack = new Stack<>();
}
if (activity != null) {
finishTheOthers(activity);
stack.add(activity);
}
}
/**
* 移除之前存在的activity
*
* @param activity
*/
public static void finishTheOthers(Activity activity) {
if (stack == null) return;
for (Iterator<Activity> it = stack.iterator(); it.hasNext(); ) {
Activity sa = it.next();
if (sa.getLocalClassName().equals(activity.getLocalClassName())) {
sa.finish();
it.remove();
}
}
}
}
一开始没有用Iterator,还报了一个错误ConcurrentModificationException(同时修改的意思)。这样就实现了我想要的效果了。