本文翻譯自:Clear the entire history stack and start a new activity on Android
Is it possible to start an activity on the stack, clearing the entire history before it? 是否可以在堆棧上啓動活動,清除之前的整個歷史記錄?
The situation 情況
I have an activity stack that either goes A->B->C or B->C (screen A selects the users token, but many users only have a single token). 我有一個活動堆棧,可以是A-> B-> C或B-> C(屏幕A選擇用戶令牌,但許多用戶只有一個令牌)。
In screen C the user may take an action which makes screen B invalid, so the application wants to take them to screen A, regardless of whether it is already in the stack. 在屏幕C中,用戶可以採取使屏幕B無效的動作,因此應用程序想要將它們帶到屏幕A,而不管它是否已經在堆棧中。 Screen A should then be the only item on the stack in my application. 屏幕A應該是我的應用程序中堆棧上唯一的項目。
Notes 筆記
There are many other similar questions, but I haven't found anything that answers this exact question. 還有許多其他類似的問題,但我沒有發現任何可以回答這個問題的問題。 I tried calling getParent().finish()
- this always results in a null pointer exception. 我試着調用getParent().finish()
- 這總是會導致空指針異常。 FLAG_ACTIVITY_CLEAR_TOP
only works if the activity is already on the stack. FLAG_ACTIVITY_CLEAR_TOP
僅在活動已在堆棧上時纔有效。
#1樓
參考:https://stackoom.com/question/EZWq/清除整個歷史記錄堆棧並在Android上啓動新活動
#2樓
在使用startActivity
開始新活動startActivity
,請確保調用finish()
以便當前活動不會堆疊在新活動後面。
#3樓
Case 1:Only two activity A and B: 案例1:只有兩個活動A和B:
Here Activity flow is A->B .On clicking backbutton from B we need to close the application then while starting Activity B from A just call finish() this will prevent android from storing Activity A in to the Backstack.eg for activity A is Loding/Splash screen of application. 這裏的活動流程是A-> B.點擊B的後退按鈕我們需要關閉應用程序然後從A啓動活動B只調用finish()這將阻止android將活動A存儲到Backstack.eg中,活動A是Loding / Splash應用程序屏幕。
Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();
Case 2:More than two activitiy: 案例2:兩個以上的活動:
If there is a flow like A->B->C->D->B and on clicking back button in Activity B while coming from Activity D.In that case we should use. 如果有來自活動D的A-> B-> C-> D-> B之類的流程以及活動B中的單擊後退按鈕。在這種情況下我們應該使用。
Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
Here Activity B will be started from the backstack rather than a new instance because of Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_NEW_TASK clears the stack and makes it the top one.So when we press back button the whole application will be terminated. 這裏活動B將從backstack而不是新實例啓動,因爲Intent.FLAG_ACTIVITY_CLEAR_TOP和Intent.FLAG_ACTIVITY_NEW_TASK清除堆棧並使其成爲最重要的一個。所以當我們按下後退按鈕時,整個應用程序將被終止。
#4樓
I spent a few hours on this too ... and agree that FLAG_ACTIVITY_CLEAR_TOP sounds like what you'd want: clear the entire stack, except for the activity being launched, so the Back button exits the application. 我也花了幾個小時...並且同意FLAG_ACTIVITY_CLEAR_TOP聽起來像你想要的那樣:清除整個堆棧,除了正在啓動的活動,所以Back按鈕退出應用程序。 Yet as Mike Repass mentioned, FLAG_ACTIVITY_CLEAR_TOP only works when the activity you're launching is already in the stack; 然而正如Mike Repass所提到的,FLAG_ACTIVITY_CLEAR_TOP僅在你正在啓動的活動已經在堆棧中時起作用; when the activity's not there, the flag doesn't do anything. 當活動不存在時,旗幟不做任何事情。
What to do? 該怎麼辦? Put the activity being launching in the stack with FLAG_ACTIVITY_NEW_TASK, which makes that activity the start of a new task on the history stack. 使用FLAG_ACTIVITY_NEW_TASK將正在啓動的活動放入堆棧,這使得該活動成爲歷史堆棧上新任務的開始。 Then add the FLAG_ACTIVITY_CLEAR_TOP flag. 然後添加FLAG_ACTIVITY_CLEAR_TOP標誌。
Now, when FLAG_ACTIVITY_CLEAR_TOP goes to find the new activity in the stack, it'll be there and be pulled up before everything else is cleared. 現在,當FLAG_ACTIVITY_CLEAR_TOP用於在堆棧中查找新活動時,它將存在並在其他所有清除之前被拉起。
Here's my logout function; 這是我的退出功能; the View parameter is the button to which the function's attached. View參數是函數附加的按鈕。
public void onLogoutClick(final View view) {
Intent i = new Intent(this, Splash.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
finish();
}
#5樓
You shouldn't change the stack. 你不應該改變堆棧。 Android back button should work as in a web browser. Android後退按鈕應該像在Web瀏覽器中一樣工作。
I can think of a way to do it, but it's quite a hack. 我可以想辦法做到這一點,但這是一個非常黑客。
Make your Activities
singleTask
by adding it to theAndroidManifest
Example: 將您的活動singleTask
添加到AndroidManifest
示例中:<activity android:name=".activities.A" android:label="@string/A_title" android:launchMode="singleTask"/> <activity android:name=".activities.B" android:label="@string/B_title" android:launchMode="singleTask"/>
Extend
Application
which will hold the logic of where to go. 擴展Application
,它將掌握去哪裏的邏輯。
Example: 例:
public class DontHackAndroidLikeThis extends Application {
private Stack<Activity> classes = new Stack<Activity>();
public Activity getBackActivity() {
return classes.pop();
}
public void addBackActivity(Activity activity) {
classes.push(activity);
}
}
From A to B: 從A到B:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class);
startActivity(this, B.class);
From B to C: 從B到C:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class);
startActivity(this, C.class);
In C: 在C:
If ( shouldNotGoBackToB() ) {
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.pop();
}
and handle the back button to pop()
from the stack. 並從堆棧處理後退按鈕pop()
。
Once again, you shouldn't do this :) 再一次,你不應該這樣做:)
#6樓
I found too simple hack just do this add new element in AndroidManifest
as:- 我發現太簡單的黑客只是在AndroidManifest
添加新元素: -
<activity android:name=".activityName"
android:label="@string/app_name"
android:noHistory="true"/>
the android:noHistory
will clear your unwanted activity from Stack. android:noHistory
將清除Stack中不需要的活動。