Làm thế nào để ngăn chặn quay trở lại hoạt động trước đó?


210

Khi nhấn nút BACK trên điện thoại, tôi muốn ngăn một hoạt động cụ thể quay lại hoạt động trước đó.

Cụ thể, tôi có màn hình đăng nhập và đăng ký, cả hai bắt đầu một hoạt động mới được gọi là HomeScreenkhi đăng nhập / đăng ký thành công. Khi HomeScreen được khởi động, tôi muốn ngăn người dùng có thể quay lại màn hình đăng nhập hoặc đăng ký bằng cách nhấn phím BACK.

Tôi đã thử sử dụng Intent.FLAG_ACTIVITY_NO_HISTORY, nhưng vì ứng dụng có tích hợp Facebook, khi 'Đăng nhập bằng Facebook' được sử dụng, Facebook sẽ quay lại màn hình đăng nhập ban đầu, do đó tôi nên giữ lại lịch sử của các hoạt động này.

Tôi đã nghĩ đến việc ghi đè hành vi của nút BACK HomeScreenđể trực tiếp hoàn thành một ứng dụng khi nhấn nút và tôi đã sử dụng

@Override
public void onBackPressed() {
    finish();
}

nhưng điều đó cũng không hoạt động.


1
Chỉ cần làm rõ, bạn đang cố gắng nắm bắt lại hành vi cho mọi người ngoại trừ facebook?
havexz

2
Trong một số trường hợp có, nhưng thực sự những gì tôi muốn là sau khi đăng nhập thành công và HomeScreen mở ra, người dùng không thể quay lại màn hình đăng nhập bằng cách nhấn nút BACK. Giống như Twitter hoặc Foursquare chẳng hạn, một khi chúng ta đăng nhập vào các ứng dụng đó, chúng ta sẽ không thấy trang đăng nhập cho đến khi chúng ta đăng xuất (ngay cả khi chúng ta nhấn BACK sau khi đăng nhập).
ecem

Câu trả lời:


345

Đề xuất của tôi sẽ là kết thúc hoạt động mà bạn không muốn người dùng quay lại. Chẳng hạn, trong hoạt động đăng nhập của bạn, ngay sau khi bạn gọistartActivity , hãy gọi finish(). Khi người dùng nhấn nút quay lại, họ sẽ không thể đi đến hoạt động đăng nhập vì nó đã bị giết khỏi ngăn xếp.


2
Điều gì xảy ra nếu tôi muốn luồng trong hoạt động trước vẫn chạy?
AlleyOOP

2
Bạn sẽ không muốn đi theo cách tiếp cận của tôi sau đó. Gọi kết thúc () sẽ giết chết hoạt động. Bạn có thể bắt đầu quá trình mà bạn muốn chạy trong hoạt động mà bạn sẽ đến không?
viên

7
Lưu ý: nếu bạn gọi finishtrong quá trình chuyển đổi được chia sẻ, bạn có thể bị chảy máu qua hoạt động trước đó. ví dụ, nếu bạn có HomeActivity-> IntermediateActivity-> FinalActivity, và bạn gọi finish()trong IntermediateActivityngay sau khi khởi động FinalActivitybạn sẽ thấy HomeActivitytrong một khoảnh khắc ngắn ngủi.
David Murdoch

101

Giải pháp sau đây có thể khá hữu ích trong kịch bản hoạt động đăng nhập / hoạt động chính thông thường hoặc thực hiện màn hình chặn.

Để thu nhỏ ứng dụng thay vì quay lại hoạt động trước đó, bạn có thể ghi đè onBackPressed()như sau:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

moveTaskToBack(boolean nonRoot)rời khỏi ngăn xếp của bạn như nó vốn có, chỉ cần đặt nhiệm vụ của bạn (tất cả các hoạt động) trong nền. Tương tự như khi người dùng nhấn nút Home .

Tham số boolean nonRoot- Nếu sai thì điều này chỉ hoạt động nếu hoạt động là gốc của một tác vụ; nếu đúng nó sẽ hoạt động cho bất kỳ hoạt động nào trong một nhiệm vụ.


3
Hoàn hảo cho một màn hình đăng nhập vì nó giữ nguyên lịch sử.
Hackmodford

Cảm ơn bạn, tôi đã cố gắng để tìm thấy điều này trong khoảng ba ngày. Vì cờ android: noHistory = "true" cho Activity không hoạt động như mong đợi (cờ noHistory tái tạo hoạt động sau khi thu nhỏ) và kết thúc () đôi khi không hoạt động với tôi, nhưng tại sao tôi vẫn không hiểu.
Denshov

37

Tôi không chắc chắn chính xác những gì bạn muốn, nhưng có vẻ như điều đó là có thể, và nó cũng có vẻ như bạn đã đi đúng hướng.

Dưới đây là một vài liên kết có thể giúp:

Vô hiệu hóa nút quay lại trong Android

  MyActivity.java =>
    @Override
    public void onBackPressed() {

       return;
    }

Làm cách nào tôi có thể tắt 'quay lại' một số hoạt động?

  AndroidManifest.xml =>
<activity android:name=".SplashActivity" android:noHistory="true"/>

1
Tôi không thể sử dụng tùy chọn noHistory vì vấn đề Facebook mà tôi đã cố gắng giải thích trong câu hỏi của mình và cũng là một trong những bình luận. Nhưng điều với nút BACK không phải là vô hiệu hóa nó, mà là làm cho nó thoát khỏi toàn bộ ứng dụng như System.exit(0)được gọi (tôi biết đó không phải là cách thực hành tốt nhất, nhưng tôi chỉ muốn đưa ra một ví dụ).
ecem

Cảm ơn điều này đã làm việc tuyệt vời. Chỉ đề nghị tôi thực hiện ở đây sẽ là, không cần phải trả lại. Chỉ cần xóa super.onBackPression (); và để trống phương thức. Điều đó cũng hoạt động tốt
hyperCoder

20

Có hai giải pháp cho trường hợp của bạn, hoạt động A bắt đầu hoạt động B, nhưng bạn không muốn quay lại hoạt động A trong hoạt động B.

1. Đã xóa hoạt động trước A khỏi ngăn xếp trở lại.

    Intent intent = new Intent(activityA.this, activityB.class);
    startActivity(intent);
    finish(); // Destroy activity A and not exist in Back stack

2. Vô hiệu hóa quay lại hành động nút trong hoạt động B.

Có hai cách để ngăn sự kiện quay trở lại như dưới đây,

1) Đề xuất phương pháp tiếp cận

@Override
public void onBackPressed() {
}

2) Ghi đè phương thức onKeyDown

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_BACK) {
        return false;
    }
    return super.onKeyDown(keyCode, event);
}

Hy vọng rằng nó hữu ích, nhưng vẫn phụ thuộc vào tình huống của bạn.


3
Có phải trải nghiệm người dùng không tệ khi vô hiệu hóa onBackPression () không?
C. Skjerdal

Nó hoàn toàn phụ thuộc vào những gì bạn đang cố gắng thực hiện, trong chức năng ứng dụng cần điều này sau đó đi cho nó.
dùng3099225

Thật đáng kinh ngạc khi tôi hoàn toàn quên mất phương pháp đầu tiên sử dụng finish(). Bất thường thay thế với nohistorythuộc tính, cờ mục đích, thẻ biểu hiện hoạt động cha mẹ, vv! Ngớ ngẩn, cảm ơn câu trả lời!
varun

8

Vì đã có nhiều giải pháp tuyệt vời được đề xuất, tôi cố gắng đưa ra một lời giải thích mang tính lưỡng lự hơn.

Làm thế nào để bỏ qua việc quay trở lại hoạt động trước đó?

Xóa Hoạt động trước đó khỏi Backstack. Đơn giản

Làm cách nào để xóa Hoạt động trước đó khỏi Backstack?

Gọi finish()Phương thức

Dòng chảy thông thường:

nhập mô tả hình ảnh ở đây
Tất cả các hoạt động được lưu trữ trong một Stack được gọi là Backstack.
Khi bạn bắt đầu một Hoạt động mới ( startActivity(...)) thì Hoạt động mới được đẩy lên trên cùng của ngăn xếp và khi bạn nhấn nút quay lại, Hoạt động được bật ra khỏi ngăn xếp.
Một điểm quan trọng cần lưu ý là khi nhấn nút quay lại thì finish();phương thức được gọi là nội bộ. Đây là hành vi mặc định của phương thức onBackPression ().

Vậy nếu bạn muốn bỏ qua Hoạt động B?

tức là A <--- C

Chỉ cần thêm finish();phương thức sau của bạn startActvity(...)trong Hoạt động B

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

nhập mô tả hình ảnh ở đây


6

finish()cung cấp cho bạn phương thức để đóng Activity hiện tại không phải toàn bộ ứng dụng. Và tốt hơn hết bạn không nên cố gắng tìm kiếm các phương pháp để hủy ứng dụng. Lời khuyên nhỏ.

Bạn đã thử kết hợp Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_HISTORY? Hãy nhớ sử dụng cờ này trong Intenthoạt động bắt đầu!


2
FLAG_ACTIVITY_NO_HISTORYngăn chặn Đăng nhập của tôi để ghi lại cuộc gọi lại của Facebook khi Đăng nhập bằng Facebook được sử dụng. Bởi vì một khi tiêu điểm ra khỏi Đăng nhập màn hình, nó không thể được nối lại (vì không có lịch sử). Nhưng tôi đã không thử nó Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, tôi sẽ kiểm tra nó, cảm ơn!
ecem

cũng cảm ơn về finish()phương pháp, tôi không biết về nó.
ecem

4

Đặt finish()ngay sau

Intent i = new Intent(Summary1.this,MainActivity.class);
            startActivity(i);
finish();

1
Đây là cơ bản những gì câu trả lời được chấp nhận từ bốn năm trước đã nói.
TylerH

3

Câu trả lời của paulsm4 là câu trả lời đúng. Nếu trong onBackPressed()bạn chỉ cần quay lại, nó sẽ vô hiệu hóa nút quay lại. Tuy nhiên, tôi nghĩ rằng một cách tiếp cận tốt hơn được đưa ra trong trường hợp sử dụng của bạn là lật logic hoạt động, nghĩa là biến hoạt động tại nhà của bạn thành chính, kiểm tra xem người dùng đã đăng nhập ở đó chưa, nếu không, hãy bắt đầu đăng nhập hoạt động. Lý do là nếu bạn ghi đè nút quay lại trong hoạt động chính của mình, hầu hết người dùng sẽ bối rối khi họ nhấn lại và ứng dụng của bạn không làm gì cả.



3

Phương pháp này đang hoạt động tốt

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

2

Chỉ cần ghi đè phương thức onKeyDown và kiểm tra xem nút quay lại đã được nhấn chưa.

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if (keyCode == KeyEvent.KEYCODE_BACK) 
    {
        //Back buttons was pressed, do whatever logic you want
    }

    return false;
}

1
@Override
public void onBackPressed() {
}

Khi bạn tạo onBackPressed()chỉ cần loại bỏ super.onBackPressed();và nó sẽ hoạt động


1

Đặt

finish();

ngay sau ActivityStart để dừng hoạt động ngăn chặn mọi cách quay lại nó. Sau đó thêm

onCreate(){
    getActionBar().setDisplayHomeAsUpEnabled(false);
    ...
}

đến hoạt động bạn đang bắt đầu.

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.