三個Activity迴圈點選,返回只保留一個本身
業務要求: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(同時修改的意思)。這樣就實現了我想要的效果了。