Kết thúc tất cả các hoạt động trước đó


368

Ứng dụng của tôi có các màn hình dòng chảy sau:

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Bây giờ tôi có một log out nút chung trong mỗi màn hình

( Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

Tôi muốn rằng khi người dùng nhấp vào nút đăng xuất (từ bất kỳ màn hình nào), tất cả các màn hình sẽ kết thúc và một màn hình mới Log insẽ mở ra.

Tôi đã cố gắng gần như tất cả FLAG_ACTIVITYđể đạt được điều này. Tôi cũng đi qua một số câu trả lời trong stackoverflow, nhưng không thể giải quyết vấn đề. Ứng dụng của tôi là trên Android 1.6 nên không thể sử dụngFLAG_ACTIVITY_CLEAR_TASK

Có cách nào để giải quyết vấn đề?


Bạn có chạy các hoạt động lồng nhau của mình bằng startActivityForResult không?
gỗ

không. Tất cả các hoạt động được bắt đầu với startActivity.
Tanmay Mandal

Tôi đang sử dụng các hoạt động lồng nhau trong khi cá tuyết chạy finishaffinitytask () trong hoạt động lồng nhau. nó có thay đổi hành vi không? vì đôi khi tôi nhận được Thất bại trong việc cung cấp kết quả resultInfo khi finishaffinitytask chạy.
Ripal Tamboli

Vui lòng kiểm tra câu trả lời này, Nó chắc chắn sẽ giúp bạn stackoverflow.com/a/25159180/2732632
Kimmi D Breathra

3
Android 21 đã giới thiệu Activity.finishAndRemoveTask ().
Joseph Johnson

Câu trả lời:


543

Sử dụng:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Điều này sẽ xóa tất cả các hoạt động trên đầu trang chủ.

Giả sử bạn đang hoàn tất màn hình đăng nhập khi người dùng đăng nhập và trang chủ được tạo và sau đó tất cả các màn hình từ 1 đến 5 trên đầu màn hình đó. Mã tôi đã đăng sẽ đưa bạn trở lại màn hình chính hoàn thiện tất cả các hoạt động khác. Bạn có thể thêm một mục đích bổ sung và đọc nó trong hoạt động trên màn hình chính và cũng hoàn thành nó (có thể khởi chạy lại màn hình đăng nhập từ đó hoặc một cái gì đó).

Tôi không chắc chắn nhưng bạn cũng có thể thử đăng nhập bằng cờ này. Tôi không biết làm thế nào các hoạt động sẽ được ra lệnh trong trường hợp đó. Vì vậy, không biết liệu nó sẽ xóa những cái bên dưới màn hình bạn đang bật bao gồm cả cái bạn đang sử dụng nhưng chắc chắn là con đường để đi.

Hi vọng điêu nay co ich.


Người dùng đang hiển thị màn hình đầu tiên của mình dưới dạng màn hình chính, đó là vấn đề chính.
Tanmay Mandal

cũng như tôi có phản hồi của tôi, bạn cần quay lại màn hình chính và hoàn thành nó. vì vậy quá trình gọi ý định trên từ bất kỳ màn hình nào. nhận được ý định trên Màn hình chính và ngay lập tức thực hiện ý định đăng nhập và kết thúc trang chủ sau phương thức startActivity. bạn cũng có thể ghi đè hình ảnh động đang chờ xử lý thành null để vào và ra để nó không hiển thị quá trình chuyển đổi (tôi làm điều đó vì nó cảm thấy nhanh hơn). Vì vậy, nó sẽ hoạt động tốt cho điều bạn cần.
DArkO

10
Thay vì khai báo hoạt động như singleInstance, hãy xem xét sử dụng FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOPlàm cờ cho Ý định. Điều này sẽ kết thúc các hoạt động can thiệp và bắt đầu (hoặc đưa trở lại nền trước) hoạt động mong muốn.
CommonsWare

13
@ CommonsWare Thêm intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);vào hoạt động của tôi không giúp tôi. Nó không hoàn thành các hoạt động can thiệp. Khi tôi nhấn lại từ màn hình Đăng nhập tôi có thể thấy các hoạt động trước đó. Đây là mã của tôi Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
Tanmay Mandal

26
mã này chỉ xóa ngăn xếp hoạt động hàng đầu, để xóa tất cả các hoạt động có ý định.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
Ajay Venugopal

318

Bạn có thể thử Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. 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.


11
Giải pháp phù hợp, nhưng chỉ API 11+
riwnodennyk

Tôi đã kết thúc bằng cách sử dụng cờ bổ sung này vì nó không gây ra sự chậm trễ khi hiển thị hoạt động chính (nó sẽ không khởi động lại để nó nhanh hơn nhiều).
Maurizio

2
@riwnodennyk tại sao API 11+?
Muhammad Babar

17
Sử dụng IntentCompat.FLAG_ACTIVITY_CLEAR_TASK cho các phiên bản trước 11
Steven Pena

2
@ono Có. Đó nên là tất cả những gì bạn cần. Đảm bảo chế độ khởi chạy của hoạt động mục tiêu của bạn được đặt là "singleTask" trong tệp kê khai.
Steven Pena

137

Trước khi khởi chạy Hoạt động mới của bạn, chỉ cần thêm mã sau đây:

finishAffinity();

Hoặc nếu bạn muốn nó hoạt động trong các phiên bản Android trước:

ActivityCompat.finishAffinity(this);

12
ActivityCompat.finishAffinity (này); gọi hoạt động.finish () cho api <16. Vì vậy, nó sẽ không hoạt động.
Aamir Abro

1
@Beto Caldas, tôi đã tự xác nhận mã nguồn, nó sẽ không hoạt động với API <16 như AamirAbro đã đề cập. Nó sẽ chỉ kết thúc hoạt động mà bạn chuyển qua API <16.
HendraWD

39

Khi người dùng muốn thoát tất cả các hoạt động đang mở , họ nên nhấn nút tải Hoạt động đầu tiên chạy khi ứng dụng của bạn khởi động, xóa tất cả các hoạt động khác, sau đó kết thúc hoạt động còn lại cuối cùng. Có đoạn mã sau chạy khi người dùng nhấn nút thoát. Trong trường hợp của tôi, LoginActivitylà hoạt động đầu tiên trong chương trình của tôi để chạy.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

Các mã trên xóa tất cả các hoạt động ngoại trừ LoginActivity. Sau đó đặt đoạn mã sau bên trong LoginActivity's onCreate(...), để lắng nghe khi LoginActivityđược tái tạo và '' tín hiệu EXIT đã được thông qua:

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Tại sao làm một nút thoát trong Android rất khó?

Android cố gắng hết sức để không khuyến khích bạn có nút "thoát" trong ứng dụng của mình, vì họ muốn người dùng không bao giờ quan tâm đến việc các chương trình họ sử dụng có chạy nền hay không.

Các nhà phát triển hệ điều hành Android muốn chương trình của bạn có thể tồn tại khi tắt máy đột ngột và tắt nguồn điện thoại và khi người dùng khởi động lại chương trình, họ sẽ chọn đúng nơi họ rời đi. Vì vậy, người dùng có thể nhận được một cuộc gọi điện thoại trong khi họ sử dụng ứng dụng của bạn và mở các bản đồ yêu cầu ứng dụng của bạn được giải phóng để có thêm tài nguyên.

Khi người dùng tiếp tục ứng dụng của bạn, họ sẽ chọn đúng nơi họ rời đi mà không bị gián đoạn. Nút thoát này đang chiếm quyền lực từ trình quản lý hoạt động, có khả năng gây ra sự cố với vòng đời chương trình Android được quản lý tự động.


31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Điều này sẽ làm việc cho tất cả các phiên bản Android. Trường hợp IntentCompatlớp được thêm vào trong thư viện Hỗ trợ Android.


IntentCompat.FLAG_ACTIVITY_CLEAR_TASKkhông được công nhận, sử dụng Intentthay vì IntentCompat.
CoolMind

30

Sử dụng như sau cho hoạt động

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.


24

Tôi đoán tôi đến muộn nhưng có câu trả lời đơn giản và ngắn gọn. Có một phương thức finishAffinity () trong Activity sẽ kết thúc hoạt động hiện tại và tất cả các hoạt động chính, nhưng nó chỉ hoạt động trong Android 4.1 trở lên.

Đối với API 16+, hãy sử dụng

finishAffinity();

Đối với dưới 16, sử dụng

ActivityCompat.finishAffinity(YourActivity.this);

Hy vọng nó giúp!


21

Từ developer.android.com :

public void finishAffinity ()

Đã thêm trong API cấp 16

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ệ. Điều này thường được sử dụng khi một ứng dụng có thể được khởi chạy sang một tác vụ khác (chẳng hạn như từ ACTION_VIEW của loại nội dung mà nó hiểu) và người dùng đã sử dụng điều hướng lên để chuyển ra khỏi tác vụ hiện tại và vào nhiệm vụ riêng của nó. Trong trường hợp này, nếu người dùng đã điều hướng xuống bất kỳ hoạt động nào khác của ứng dụng thứ hai, tất cả những hoạt động đó sẽ bị xóa khỏi tác vụ gốc như một phần của chuyển đổi tác vụ.

Lưu ý rằng kết thúc này không cho phép bạn cung cấp kết quả cho hoạt động trước đó và một ngoại lệ sẽ được đưa ra nếu bạn đang cố gắng thực hiện.


19

Bên cạnh đó, cần biết
Câu trả lời này hoạt động ( https://stackoverflow.com/a/13468685/7034327 )

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

trong khi điều này không hoạt động

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() thay thế bất kỳ cờ nào trước đó và không nối thêm bất kỳ cờ mới nào trong khi .addFlags()đó.

Vì vậy, điều này cũng sẽ làm việc

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Giải thích tuyệt vời về sự khác biệt giữa setFlag so với addFlag, cảm ơn bạn
Pelanes

13

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


10

Một giải pháp tôi đã thực hiện cho việc này (tôi nghĩ rằng tôi đã tìm thấy nó trên Stack Overflow ở đâu đó, nhưng tôi không nhớ, vì vậy, bất cứ ai đã làm điều đó ở nơi đầu tiên):

Từ bất kỳ hoạt động nào của bạn làm điều này:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Sau đó, trong phần Đăng nhập của bạn, ghi đè lên onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3
Đó thường là một ý tưởng rất tồi, nó có thể hoạt động, nó giới thiệu một điểm liên lạc có thể bị phá vỡ trong tương lai và sẽ rất khó để gỡ lỗi. Tôi đang kể cho bạn từ kinh nghiệm :)
Martin Marconcini

10

Đối với nút đăng xuất trên màn hình cuối cùng của ứng dụng, hãy sử dụng mã này trên trình nghe nút đăng xuất để hoàn tất tất cả các hoạt động đã mở trước đó và vấn đề của bạn đã được giải quyết.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}

8
    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();

6
tại sao FLAG_ACTIVITY_CLEAR_TASK hai lần?
Choletski

1
Theo những gì tôi hiểu, .setFlags thay thế các cờ trước đó và không nối thêm bất kỳ cờ nào. .addFlags là những gì bạn muốn sử dụng tôi đoán? Nguyên nhân tất cả các mã ở trên i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); bị xóa sổ
iOSAndroidWindowsMobileAppsDev 14/03/2016

addFlags Hoạt động cho tôi
Jamil

1
setFlagssẽ thay thế tất cả trước đó, vì vậy cuối cùng setFlagschỉ có giá trị, trước đó được thay thế. Vì vậy, bạn không cần phải gọii1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
mtrakal

8

Tôi có cùng một vấn đề bạn có thể sử dụng IntentCompat, như thế này:

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

mã này làm việc cho tôi.

Api 17


8

Trong trường hợp của tôi, tôi sử dụng finishAffinity()chức năng trong hoạt động cuối như:

finishAffinity()
startHomeActivity()

Hy vọng nó sẽ hữu ích.



6

Đăng nhập-> Trang chủ-> màn hình 1-> màn hình 2-> màn hình 3-> màn hình 4-> màn hình 5

trên màn hình 4 (hoặc bất kỳ thứ gì khác) ->

StartActivity (Đăng nhập)
với
FLAG_ACTIVITY_CLEAR_TOP


2
Khi tôi nhấn nút quay lại, tất cả các hoạt động trước đó được hiển thị theo thứ tự chúng. Các hoạt động này cần phải được đóng lại, khi nút đăng xuất nhấp vào sẽ chỉ có một hoạt động trong ngăn xếp và đó sẽ là hoạt động đăng nhập. đăng nhập màn hình. Người dùng bắt đầu từ màn hình chính.
Tanmay Mandal

6

cho API> = 15 đến API 23 giải pháp đơn giản.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

Xây dựng câu trả lời của bạn để mọi người có thể hưởng lợi từ nó.
Shubhamoy

5

Nếu bạn đang sử dụng startActivityForResult()trong các hoạt động trước đó của mình, chỉ cần ghi đè OnActivityResult()và gọi finish();phương thức bên trong nó trong tất cả các hoạt động .. Điều này sẽ thực hiện công việc ...


Không, tôi startActivitychỉ sử dụng .
Tanmay Mandal

Sẽ rất khó để duy trì onActivityResulttrên mỗi hoạt động. Tôi đã thực hiện đề xuất của DArkO và đạt được mục tiêu của tôi và cảm ơn vì sự giúp đỡ.
Tanmay Mandal

3

Khi người dùng nhấp vào nút đăng xuất, sau đó viết đoạn mã sau:

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

Và cũng như sau khi đăng nhập nếu bạn gọi hoạt động mới không sử dụng kết thúc ();


2

Đơn giản, khi bạn đi từ màn hình đăng nhập, không phải khi kết thúc màn hình đăng nhập.

Và sau đó trong tất cả các hoạt động chuyển tiếp, sử dụng điều này để đăng xuất:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

Nó hoạt động hoàn hảo.


1

Nếu bạn đăng nhập người dùng vào screen 1và từ đó bạn đi đến các màn hình khác, hãy sử dụng

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

Khi tôi nhấn nút quay lại, tất cả các hoạt động trước đó được hiển thị theo thứ tự chúng. Các hoạt động cần phải được đóng lại, khi nút đăng xuất nhấp vào sẽ chỉ có một hoạt động trong ngăn xếp và đó sẽ là hoạt động đăng nhập.
Tanmay Mandal

Nếu bạn muốn hành vi này, bạn phải ghi đè onKeyDownonBackPressed(hoặc onKeyDown, nếu bạn muốn hỗ trợ các phiên bản Android <2.0) trong mỗi hoạt động của mình (ngoại trừ hoạt động đăng nhập) và startActivity(login)ở đó như được hiển thị ở trên.
Gabriel Negut

Tôi có một nút sẽ đưa tôi đến màn hình đăng nhập hoàn tất tất cả các hoạt động trong ngăn xếp. Có thể không?
Tanmay Mandal

1

Tôi tìm thấy theo cách này, nó sẽ xóa tất cả lịch sử và thoát

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);

1

Tôi đoán tôi đến muộn nhưng có câu trả lời đơn giản và ngắn gọn. Có một phương thức finishAffinity () trong Activity sẽ kết thúc hoạt động hiện tại và tất cả các hoạt động chính, nhưng nó chỉ hoạt động trong Android 4.1 trở lên.

Đối với API 16+, hãy sử dụng

kết thúcAffality ();

Đối với dưới 16, sử dụng

ActivityCompat.finishAffinity (YourActivity.this);

Hy vọng nó giúp!

shareedit đã trả lời 27 tháng 5 năm 18 lúc 8:03

Akshay Taru


0

Tôi thấy giải pháp này hoạt động trên mọi thiết bị mặc dù ở cấp độ API (ngay cả đối với <11)

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

0

Cách tốt nhất để đóng tất cả các hoạt động trước đó và xóa bộ nhớ

finishAffinity()
System.exit(0);

0
startActivity(
                Intent(this, LoginActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .addFlags(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.