Android: Xóa tất cả các hoạt động trước đó khỏi ngăn xếp phía sau


119

Khi tôi nhấp vào nút Đăng xuất trong Hoạt động hồ sơ của mình, tôi muốn đưa người dùng đến trang Đăng nhập , nơi anh ta cần sử dụng thông tin đăng nhập mới.

Do đó tôi đã sử dụng mã này:

Intent intent = new Intent(ProfileActivity.this,
        LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

trong onButtonClicknút Đăng xuất.

Nhưng vấn đề là khi tôi nhấp vào nút quay lại thiết bị trên Hoạt động đăng nhập, nó sẽ đưa tôi đến ProfileActivity. Tôi đã mong đợi ứng dụng sẽ đóng khi tôi nhấn nút quay lại thiết bị trên LoginActivity.

Tôi đang làm gì sai?

Tôi cũng đã thêm android:launchMode="singleTop"vào tệp kê khai cho LoginActivity của mình

Cảm ơn bạn


@GauravVashisth Tôi vừa mới làm theo giải pháp này stackoverflow.com/questions/5794506/…
Archie.bpgc

@ abbas.aniefa Giải pháp đó tôi hơi phức tạp. Đó có phải là cách duy nhất để xóa tất cả các back stack. Bởi vì tôi có hơn 30 hoạt động vì vậy tôi nên viết mã phát sóng này cho tất cả trong số họ
Archie.bpgc

hãy thử điều này sau đó, stackoverflow.com/questions/10961481/… . Sử dụng Broadcast là một giải pháp tốt hơn.
abbas.aniefa

một cách tiếp cận khác mà bạn có thể sử dụng để đăng xuất, khi bạn đăng xuất lưu trữ một cờ trong phần tham chiếu được chia sẻ và trong mỗi phương thức onRestart () của một hoạt động, bạn có thể kiểm tra giá trị biến này nếu nó được đặt thành true, bạn có thể kết thúc hoạt động hiện tại. vì vậy bất kể có bao nhiêu hoạt động đang mở trong backgroud. điều này sẽ kết thúc tất cả hoạt động của bạn.
Hiren Dabhi

Mã gốc của bạn thực sự hoạt động cho API cấp 11 trở lên với một sự tinh chỉnh. Bạn chỉ cần đặt những lá cờ với nhau trong một cuộc gọi duy nhất: intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);Tôi nhận được câu trả lời từ câu hỏi này: stackoverflow.com/questions/3473168/...
jokeefe

Câu trả lời:


302

Giải pháp được đề xuất ở đây phù hợp với tôi:

Java

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Kotlin

val i = Intent(this, NewActivity::class.java)
// set the new task and clear flags
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)

Tuy nhiên, nó yêu cầu cấp API> = 11.


Các bạn, hãy đọc tài liệu của FLAG_ACTIVITY_CLEAR_TASK. Đây là cách chính thức để có được. Không cần phải thay đổi tất cả các hoạt động trong ứng dụng.
AlikElzin-kilaka

Điều này không hoạt động đối với thông báo stackoverflow.com/questions/24873131/…
Sam

Tôi có minAPI = 16, vì vậy điều này đang hoạt động hoàn toàn tốt đối với tôi. Tuy nhiên, tôi nhận thấy rằng việc thực thi chế độ xem hơi chậm chạp với API> 21 và mượt mà với API <21. Có ai gặp vấn đề tương tự không?
Red M

1
Điều này sẽ tạo ra một Nhiệm vụ mới cho các hoạt động
Rohit

@kgiannakakis Không nghi ngờ gì giải pháp đang hoạt động nếu chúng ta chỉ có một tác vụ (ngăn xếp Hoạt động trở lại) nhưng khi chúng tôi có nhiều tác vụ (ngăn xếp hoạt động) thì nó không hoạt động. Ví dụ: giả sử tôi có bốn hoạt động cho ứng dụng của mình A, B, C & D. Giả sử tôi có hai ngăn xếp Hoạt động lùi A-> B-> C (nền) & D-> A-> B (Nền trước) và Nếu tôi gọi hoạt động A từ ngăn xếp hiện tại của tôi (D-> A-> B) với bộ lọc ý định những gì bạn đã đề xuất điều gì sẽ xảy ra. Nó sẽ xóa ngăn xếp hiện tại của tôi (D-> A-> B) và mở hoạt động A và khi tôi nhấn lại thì đóng ứng dụng nhưng nếu tôi nhấn nút ứng dụng gần đây, tôi có thể thấy hai ngăn xếp phía sau của Ứng dụng của tôi ở đó.
Rahul Pareta

31

Đây là một giải pháp để xóa tất cả các hoạt động của ứng dụng khi bạn sử dụng nút đăng xuất.

Mỗi khi bạn bắt đầu một Hoạt động, hãy bắt đầu nó như sau:

Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class);
startActivityForResult(myIntent, 0);

Khi bạn muốn đóng toàn bộ ứng dụng, hãy làm như sau:

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL là biến toàn cục cuối cùng có số nguyên duy nhất để báo hiệu bạn muốn đóng tất cả các hoạt động.

Sau đó, xác định lệnh onActivityResult(...)gọi lại của mọi hoạt động để khi một hoạt động trả về với giá trị RESULT_CLOSE_ALL, nó cũng sẽ gọi finish():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Điều này sẽ gây ra hiệu ứng thác đóng tất cả các hoạt động của bạn.

Tuy nhiên, đây là một bản hack và sử dụng startActivityForResulttheo cách mà nó không được thiết kế để sử dụng.

Có lẽ một cách tốt hơn để làm điều này là sử dụng bộ thu phát sóng như được hiển thị ở đây:

Khi đăng xuất, xóa ngăn xếp Lịch sử hoạt động, ngăn nút "quay lại" mở các Activite chỉ đăng nhập

Xem các chủ đề này để biết các phương pháp khác:

Android: Xóa ngăn xếp phía sau

Hoàn thành tất cả các hoạt động trước đó


4
Có khả thi không khi bạn có khoảng 30 hoạt động trên lịch sử ??
Rakesh Gondaliya

4
nên là. Nhưng nếu bạn có 30 hoạt động trong lịch sử thì bạn có thể muốn xem xét thay đổi thiết kế của mình. 30 dường như hơi quá và Android có thể tự giết chúng.
Anup Cowkur

1
Đây có vẻ là một cách làm kém hiệu quả. Câu trả lời của @RakeshGondaliya có vẻ hợp pháp. 30 có thể chỉ là một con số đại diện cho một số lượng hoạt động 'cao'. Câu trả lời này có vẻ tốt hơn: stackoverflow.com/a/3008684/243709
Aman Alam,

Câu trả lời này là tuyệt vời. Bạn cũng có thể sử dụng thư viện EventBus để gửi các sự kiện đến các hoạt động của mình trong backstack. github.com/greenrobot/EventBus
Stan

Tốt hơn nên sử dụng cờ 'Intent.FLAG_ACTIVITY_CLEAR_TOP' đơn giản với mục đích
Naveen Rao

18

Để xóa hoàn toàn ngăn xếp hoạt động, bạn muốn tạo một ngăn xếp tác vụ mới bằng TaskStackBuilder, ví dụ:

Intent loginIntent = LoginActivity.getIntent(context);
TaskStackBuilder.create(context).addNextIntentWithParentStack(loginIntent).startActivities();

Điều này sẽ không chỉ tạo ra một ngăn xếp nhiệm vụ mới, sạch sẽ mà còn cho phép nút "lên" hoạt động bình thường nếu LoginActivity của bạn có hoạt động chính.


1
Đây là cách tốt nhất để làm điều đó.
Paul Burke

FLAG_ACTIVITY_NEW_TASKhoặc finishAffinity()không hiệu quả với tôi. Chỉ câu trả lời này đã giải quyết được mục đích.
TM

Nếu tôi rời khỏi ứng dụng qua nút quay lại và quay lại qua biểu tượng ứng dụng, nó sẽ mở ra trong hoạt động mà tôi gọi là phương pháp đó. Vì vậy, không làm việc cho tôi.
Tgo1014,

17

finishAffinity()được thêm vào trong API 16. Sử dụng ActivityCompat.finishAffinity()trong các phiên bản trước. Khi bạn sẽ khởi chạy bất kỳ hoạt động nào sử dụng ý định và kết thúc hoạt động hiện tại. Bây giờ sử dụng ActivityCompat.finishAffinity()thay thế finish(). nó sẽ kết thúc tất cả hoạt động xếp chồng bên dưới hoạt động hiện tại. Việc này ổn với tôi.


3
Nó thực sựActivityCompat.finishAffinity()
The Berga

finishAffinity()cũng kết thúc hoạt động hiện tại với tất cả các hoạt động có trong ngăn xếp phía sau của cùng một mối quan hệ.
Neeraj Sewani

10

Điều gì đã làm việc cho tôi

Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

5

Một giải pháp khả thi mà tôi có thể đề xuất cho bạn là thêm android:launchMode="singleTop"vào tệp kê khai cho ProfileActivity của tôi . và khi nhấp vào đăng xuất bạn có thể đăng xuất bắt đầu lại bạn LoginActivity. khi đăng xuất bạn có thể gọi cái này.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();

Tôi đã làm điều này, những gì xảy ra là: khi tôi bấm lại nút tôi phải mất đến Activty từ nơi tôi đến ProfileActivity
Archie.bpgc

Điều này có thể xảy ra vì bạn đến với ProfileActivity bằng cách gọi một ý định mới chứ không phải bằng cách gọi finish (); Làm thế nào bạn đến với ProfileActivity từ hoạt động khác ngoài LoginActivty?
Android

Tôi đang vượt qua cùng một câu hỏi. Tôi nghĩ rằng nó sẽ không hoạt động khi ý định Đăng nhập bị phá hủy bởi hệ thống, chẳng hạn như do thiếu memroy.
user1914692

5

Đối với API 11+, bạn có thể sử dụng Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASKnhư sau:

Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);

Nó sẽ hoàn toàn xóa tất cả (các) hoạt động trước đó và bắt đầu hoạt động mới.


4

Bạn có thể thử finishAffinity(), nó đóng tất cả các hoạt động hiện tại và hoạt động trên Android 4.1 trở lên


1
finishAffinity () được thêm vào API 16. Sử dụng ActivityCompat.finishAffinity () trong phiên bản trước. Tôi làm việc tốt cho tôi.
Anurag Srivastava

2

Tôi cũng đang phải đối mặt với cùng một vấn đề..

trong hoạt động đăng nhập những gì tôi làm là.

    Intent myIntent = new Intent(MainActivity.this, ActivityLoggedIn.class);
    finish();
    MainActivity.this.startActivity(myIntent);  

đăng xuất

   Intent myIntent = new Intent(ActivityLoggedIn.this, MainActivity.class);
   finish();
   ActivityLoggedIn.this.startActivity(myIntent);

Điều này hoạt động tốt nhưng khi tôi ở trong ActivityLoggedIn và tôi thu nhỏ ứng dụng và nhấp vào biểu tượng nút trình khởi chạy trên ngăn ứng dụng, MainActivity bắt đầu lại: - / tôi đang sử dụng cờ

android:LaunchMode:singleTask 

cho MainActivity.


2

Sử dụng phần sau cho activity

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

xóa cờ CLEAR_TASK để sử dụng phân đoạn.

Tôi hy vọng điều này có thể sử dụng cho một số người.


1

Chỉ cần giữ

Intent intent = new Intent(ProfileActivity.this,
    LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

4
Nó không hoạt động. Tôi vẫn có thể đến vào nút quay lại ProfileActivity sử dụng
Archie.bpgc

1

Không có cờ dự định nào phù hợp với tôi, nhưng đây là cách tôi sửa nó:

Khi người dùng đăng xuất khỏi một hoạt động, tôi phải phát thông báo từ hoạt động đó, sau đó nhận thông báo đó trong các hoạt động mà tôi muốn đóng sau đó tôi gọi là finish (); và nó hoạt động khá tốt.


1

Hãy thử nó sẽ hoạt động:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();

1

Trong API cấp 11 trở lên, hãy sử dụng FLAG_ACTIVITY_CLEAR_TASKFLAG_ACTIVITY_NEW_TASKgắn cờ trên Intent để xóa tất cả ngăn xếp hoạt động.

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |  Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

0

Dùng cái này

Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

bạn đã biết setFlags và addFlags chưa?
GvSharma

0

thêm vào Manifest cho hoạt động của bạn android:launchMode="singleTask"


0

Kotlin nâng cao, có thể tái sử dụng:

Bạn có thể đặt cờ trực tiếp bằng phương pháp setter. Trong Kotlin orlà sự thay thế cho Java bitwise hoặc |.

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Nếu bạn định sử dụng nó thường xuyên, hãy tạo một chức năng mở rộng Intent

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Sau đó, bạn có thể gọi trực tiếp hàm này trước khi bắt đầu ý định

intent.clearStack()

Nếu bạn cần tùy chọn để thêm cờ bổ sung trong các tình huống khác, hãy thêm một tham số tùy chọn vào chức năng mở rộng.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.