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


330

Trong Android tôi có một số hoạt động, giả sử A, B, C.

Trong A, tôi sử dụng mã này để mở B:

Intent intent = new Intent(this, B.class);
startActivity(intent);

Trong B, tôi sử dụng mã này để mở C:

Intent intent = new Intent(this, C.class);
startActivity(intent);

Khi người dùng chạm một nút trong C, tôi muốn quay lại A và xóa ngăn xếp phía sau (đóng cả B và C). Vì vậy, khi người dùng sử dụng nút quay lại B và C sẽ không hiển thị, tôi đã thử các cách sau:

Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

Nhưng B và C vẫn hiển thị nếu tôi sử dụng nút quay lại khi tôi quay lại hoạt động A. Làm thế nào tôi có thể tránh điều này?

Câu trả lời:


437

Hãy thử thêm FLAG_ACTIVITY_NEW_TASKnhư được mô tả trong các tài liệu cho FLAG_ACTIVITY_CLEAR_TOP:

Chế độ khởi chạy này cũng có thể được sử dụng để có hiệu quả tốt khi kết hợp với FLAG_ACTIVITY_NEW_TASK: nếu được sử dụng để bắt đầu hoạt động gốc của một tác vụ, nó sẽ đưa bất kỳ trường hợp nào đang chạy của tác vụ đó lên nền trước, sau đó xóa nó về trạng thái gốc. Điều này đặc biệt hữu ích, ví dụ, khi khởi chạy một hoạt động từ trình quản lý thông báo.

Vì vậy, mã của bạn để khởi chạy Asẽ là:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
CurrentActivity.this.finish(); // if the activity running has it's own context


// view.getContext().finish() for fragments etc.

28
Cảm ơn nhưng tôi đã thử nó. Vẫn khi tôi chạm vào nút quay lại sau khi nó hiển thị lại C. Tôi có thể thiếu gì?
Martin

4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
dzeikei

8
không hoạt động đối với tôi tuy nhiên việc gọi kết thúc () cho hoạt động nguồn thực hiện những gì tôi cần đạt được
2cupsOfTech 23/07/14

10
Tôi đã có cùng một vấn đề rằng điều này đã không làm việc. Điều cố định với tôi là gọi kết thúc () sau khi bắt đầu hoạt động mới
Arno

20
Tôi cũng đã thêm một mục đích rõ ràng hơn Ý định mới = Ý định mới (SingUpActivity.this, LoginActivity. Class); aim.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (ý định); hoàn thành();
Sam

146
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

8
Với tất cả sự tôn trọng đối với CLEAR_TOPcờ - sự kết hợp này là sự kết hợp DUY NHẤT đã xóa hoàn toàn toàn bộ ngăn xếp và làm cho hoạt động mới trở thành hoạt động duy nhất trong ứng dụng. Cảm ơn bạn!
Aviel Gross 8/03/2015

8
Điều gì khác biệt giữa câu trả lời này và câu trả lời được chấp nhận?
Yuri Heupa

7
Cảm ơn, sự khác biệt với câu trả lời được chấp nhận là với lá cờ này, chúng tôi không cần phải gọi hoạt
động.finish

1
FLAG_ACTIVITY_CLEAR_TASK đã hoạt động hoàn hảo cùng với NEW_TASK
Shamsul Arefin Sajib

1
Đây phải là câu trả lời được chấp nhận. Cảm ơn rât nhiều.
MD Đan Mạch Ansari

77

Điều gì về việc thêm vào tệp kê khai cho hoạt động liên quan:

android:noHistory="true"

đến định nghĩa hoạt động của B và C? Họ sẽ không được thêm vào backstack. Không chắc chắn nếu đó là những gì bạn muốn.


3
Hãy cẩn thận trong khi sử dụng cái này - Nếu bạn đang sử dụng đăng nhập bằng FB hoặc bất kỳ loại chức năng tương tự nào
Skynet

2
@Skynet Tại sao? Các vấn đề liên quan đến việc này là gì?
Alfie Woodland

8
Khi bạn chuyển quyền kiểm soát tới FB để đăng nhập từ một trang không có thông tin là đúng, ứng dụng FB hiện không xuất hiện sau khi đăng nhập người dùng, trong trường hợp của tôi, nó đã quay trở lại màn hình chính của điện thoại và tôi gần như mất việc!
Skynet

Điều này không cho phép một hoạt động được thêm vào backstack .... đây không phải là giải pháp chính xác.
Tarun

Chính xác là tôi đang tìm kiếm
Masum

63

Điều này làm phiền tôi trong một thời gian dài. Cuối cùng, tôi đã giải quyết nó bằng cách làm điều này:

Trong đoạn, sử dụng:

Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

Trong Hoạt động, sử dụng (thêm một cờ mục đích Intent.FLAG_ACTIVITY_CLEAR_TASKso với đoạn):

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

1
Nếu bạn đang sử dụng androidannotations, bạn phải thêm: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade

Hoạt động solutioin làm việc tốt cho tôi. Mặc dù tôi nghĩ với API 16, giải pháp từ Daniel Schuler dễ dàng hơn.
PhilippS

Cảm ơn bạn yosafatade, đó là những gì tôi đã thiếu!
Marty Miller

30
  1. Thêm vào android:launchMode="singleTop" thành phần hoạt động trong bảng kê khai của bạn cho Hoạt động A
  2. Sau đó sử dụng intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)khi bắt đầu Hoạt động A

Điều này có nghĩa là khi Hoạt động A được khởi chạy, tất cả các tác vụ trên đầu trang sẽ bị xóa để A đứng đầu. Một ngăn xếp mới được tạo với A ở gốc và sử dụng singleTopđảm bảo bạn chỉ khởi chạy A một lần (vì A hiện đang ở trên đỉnh do ..._CLEAR_TOP).


3
Đúng. đây là những gì tôi đang sử dụng nhưng không được. Vẫn C xuất hiện khi tôi nhấn nút quay lại.
Martin

Kì lạ, tôi đã sử dụng nó trong một dự án và nó hoạt động tốt ... nhấn trở lại sẽ đưa tôi đến màn hình chính. Có lẽ có điều gì khác đang xảy ra. Bạn có thể gửi bản kê khai của bạn?
Joseph Earl

Tôi đã khởi động lại trình giả lập và bây giờ nó có vẻ hoạt động giống như bạn nói. Cảm ơn sự giúp đỡ của bạn!
Martin

SingleTop không có gì để làm với việc xóa ngăn xếp.
xuất hiện

29

Bắt đầu trong API 16 (Jelly Bean), bạn chỉ có thể gọi finishAffinity() .

Bây giờ bạn cũng có thể gọi ActivityCompat.finishAffinity(Activity activity) với thư viện tương thích.

Hãy chắc chắn đặt taskAffality trong tệp kê khai thành tên gói duy nhất cho nhóm hoạt động đó.

Xem để biết thêm thông tin:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


Giải pháp thực sự hữu ích và dễ sử dụng nếu bạn đã đọc về API 16. Đã làm việc cho tôi!
PhilippS

3
nhắc nhở: điều này sẽ chỉ hoạt động đối với các hoạt động có cùng nhiệm vụ Tên hiệu quả
Ryan

Điều này chỉ hoạt động nếu bạn chỉ có một hoạt động trong lịch sử.
arsent

17

Hãy thử sử dụng

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

và không

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

11

Nếu ứng dụng của bạn có sdk tối thiểu phiên bản 16 thì bạn có thể sử dụng finishAffinity ()

Kết thúc hoạt động này cũng như tất cả các hoạt động ngay bên dưới nó trong nhiệm vụ hiện tại có cùng mối quan hệ.

Đây là công việc đối với tôi Trong màn hình Thanh toán hàng đầu loại bỏ tất cả các kích hoạt ngăn xếp lại,

 @Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29



8

Để nghiên cứu trong tương lai, hãy thử mã này.

Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();

Những lá cờ cuối cùng đã làm việc cho tôi. Những gì tôi đã làm là tôi bắt đầu cùng một Hoạt động tôi đã có với những lá cờ này và một EXIT boolean thêm = true. Trong onCreate () tôi đã kiểm tra các tham số khởi chạy cho EXIT và được gọi là finish () nếu nó được đặt thành true. Đó là rất nhiều rắc rối chỉ để đóng ứng dụng của riêng bạn.
Janne Oksanen

8

Sử dụng finishAffinity (); trong nhiệm vụ C khi bắt đầu nhiệm vụ A để xóa các hoạt động backstack.


chỉ câu trả lời này làm việc cho tôi. Intent.FLAG_ACTIVITY_CLEAR_TOP và Intent.FLAG_ACTIVITY_NEW_TASK không bắt buộc
nuttynibble

7

Sử dụng mã này để bắt đầu một Hoạt động mới và đóng hoặc hủy tất cả ngăn xếp hoạt động khác hoặc ngăn xếp lại.

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

5
Use finishAffinity() to clear all backstack with existing one.

Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 

    - Activity B will be finished / removing from stack.
    - Activity A will be finished / removing from stack.
    - Activity C will finished / removing from stack.

5

Tôi tìm thấy một giải pháp thú vị mà có thể giúp đỡ. Tôi đã làm điều này trong onBackPressed()phương pháp của tôi .

finishAffinity();
finish();

FinishAffinityloại bỏ kết nối của hoạt động hiện có với ngăn xếp của nó. Và sau đó kết thúc giúp bạn thoát khỏi hoạt động đó. Mà cuối cùng sẽ thoát khỏi ứng dụng.


4

Tôi tìm thấy câu trả lời ở đây một chút sai lệch bởi vì mã trong câu hỏi ban đầu dường như hoạt động tốt cho tôi?

Với A là hoạt động gốc, chỉ bắt đầu từ B hoặc C với FLAG_ACTIVITY_CLEAR_TOP sẽ loại bỏ B và C khỏi ngăn xếp phía sau.


4

Trong kotlin nó gần giống như java. Chỉ | biểu tượng được thay thế bằng hoặc văn bản. Vì vậy, nó được viết như-

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

3

Tôi đã thử tất cả các giải pháp và không có giải pháp nào làm việc riêng cho tôi. Giải pháp của tôi là:

Khai báo Activity Anhư SingleTopbằng cách sử dụng [android:launchMode="singleTop"]trong bảng kê khai Android.

Bây giờ thêm các cờ sau trong khi khởi chạy Atừ bất cứ đâu. Nó sẽ xóa ngăn xếp.

Intent in = new Intent(mContext, A.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(in);
finish();

2

Intent.FLAG_ACTIVITY_CLEAR_TOPsẽ không hoạt động trong trường hợp này. Vui lòng sử dụng(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Để biết thêm chi tiết xin vui lòng kiểm tra tài liệu này .


2

Nghe có vẻ với tôi như bạn cần phải bắt đầu Activity Ctừ Activity Bbằng cách sử dụng startActivityForResult(). Khi bạn nhấp vào một nút trong Activity C, gọi setResult(RESULT_OK)finish()như vậy Activity Clà kết thúc. Trong Activity B, bạn có thể có onActivityResult()phản hồi bằng cách tự gọi finish()và sau đó bạn sẽ được đưa trở lại Activity A.


7
Có, nhưng nếu có 42 hoạt động giữa A và C, điều này sẽ khá tẻ nhạt. Cờ FLAG_ACTIVITY_CLEAR_TOP được cho là thực hiện trực tiếp những gì OP muốn.
Guillaume Brunerie

Đây sẽ là một cách ít hơn tối ưu để đạt được những gì OP muốn, và như @Guillaume nói, nó sẽ yêu cầu mã trong tất cả các hoạt động giữa gốc và đỉnh của ngăn xếp.
Jake Basile

Ghi nhận hợp lệ. Đây là những lá cờ tôi cần tìm hiểu về rõ ràng.
Maximus

1

logout.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);


1

Bạn có thể sử dụng ví dụ này để gọi Activity AtừActivity C

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);


1

cho tôi thêm Intent.FLAG_ACTIVITY_CLEAR_TASKgiải quyết vấn đề

Intent i = new Intent(SettingsActivity.this, StartPage.class);
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
finish();

1

Kotlin tiên tiến, có thể tái sử dụng:

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

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Nếu sử dụng nhiều lần, hãy tạo chức năng mở rộng Ý định

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 chức năng này trước khi bắt đầu ý định

intent.clearStack()

Nếu bạn cần tùy chọn để thêm các 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
}

0

Ngoài ra FLAG_ACTIVITY_CLEAR_TOP, bạn cũng có thể thử thêm Intent.FLAG_ACTIVITY_SINGLE_TOP:

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


Điều đó sẽ chỉ ảnh hưởng đến hoạt động ở đầu ngăn xếp chứ không ảnh hưởng đến gốc của nó.
Jake Basile

0

Mã đã cho hoạt động chính xác. Tôi đã thử trong mẫu Vòng đời ứng dụng.

Tôi chưa có B và C trong ngăn xếp sau khi bắt đầu hoạt động A với cờ, FLAG_ACTIVITY_CLEAR_TOP


0

tôi gọi activity_name.this.finish()sau khi bắt đầu ý định mới và nó đã làm việc cho tôi.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Nhưng nó sẽ không hiệu quả với tôi ... Tôi không gợi ý giải pháp này để sử dụng nhưng nếu cài đặt cờ sẽ không hiệu quả với bạn hơn bạn có thể thử điều này..Nhưng tôi vẫn khuyên bạn không nên sử dụng nó


0

Thêm KHÔNG Lịch sử cờ trong ý định.

Trong hoạt động B, bắt đầu hoạt động C như sau >>>>>>

Intent intent = new Intent(this, C.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
startActivity(intent);
finish();

0

Trong bảng kê khai

android:launchMode="singleTask"

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

0

Hoặc thêm nó vào của bạn Activity BActivity C

android:noHistory="true"

hoặc Override onBackPressedchức năng để tránh nhấn trở lại với a return.

@Override
public void onBackPressed() {
   return;
}

0

Sử dụng phương thức setFlags () để xóa mặt sau mở tất cả hoạt động đóng và bắt đầu Trọng lực của bạn

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
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.