Android: mở hoạt động mà không cần lưu vào ngăn xếp


94

Tôi có 2 hoạt động: Chính và Danh sách.

Từ Chính, bạn có thể mở Danh sách; từ Danh sách bạn có thể mở Chính.

Tôi muốn nó để mọi lần mở Danh sách không bị lưu vào 'lịch sử'. Vì vậy, nhấn lại từ Chính không thể trở lại Danh sách.

Nó có khả thi không?


11
Nếu 'danh sách' bắt đầu 'chính' thì nó sẽ được gọi finish()ngay sau đó startActivity(...). Bằng cách đó, nếu người dùng nhấn QUAY LẠI từ 'chính' sẽ không có gì để quay lại.
Squonk

điều này là để điều hướng thông báo nhưng các khái niệm có thể áp dụng developer.android.com/guide/topics/ui/notifiers/…
Kevin Lee,

Câu trả lời:


159

Khi bắt đầu danh sách của bạn Activity, hãy đặt Intentcờ của nó như sau:

Intent i = new Intent(...); // Your list's Intent
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); // Adds the FLAG_ACTIVITY_NO_HISTORY flag
startActivity(i);

Các FLAG_ACTIVITY_NO_HISTORYcờ giữ mới Activitytừ được thêm vào lịch sử stack.

NB: Như @Sam đã chỉ ra, bạn có thể sử dụng i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);thay thế. Không có sự khác biệt về chức năng.


2
Chỉ cần nhận xét một chút về phương pháp này: phương pháp này sẽ hoạt động hoàn hảo nếu chỉ có 2 Hoạt động. Nhưng nếu Hoạt động danh sách có khả năng khởi động Hoạt động khác (hãy nói Hoạt động thứ ba), một nền báo chí để nút quay lại trong Hoạt động thứ ba sẽ trở về Hoạt động chính và không phải là danh sách Hoạt động
VinceFR

Thật. Thật không may, không có cách nào để tránh điều đó. Không có Intentlá cờ nào nói rằng "chỉ thêm vào lịch sử nếu không trở lại Activitynguồn gốc".
Eric

1
không nhưng cờ FLAG_ACTIVITY_NEW_TASK sẽ thực hiện công việc, danh sách Hoạt động sẽ được thêm vào lịch sử nhưng luôn ở trên cùng, do đó, một cú nhấn ngược từ Hoạt động chính sẽ không hiển thị danh sách Hoạt động
VinceFR

6
Có bất kỳ lý do đặc biệt mà bạn sử dụng setFlags()với getFlags()thay vì Intent.addFlags()?
Sam

1
@VinceFR đó chính xác là những gì tôi muốn! a -> b -> c và lợi nhuận trực tiếp đến c-
realtebo

89

Trong tệp kê khai, hãy thêm:

android:noHistory="true" 

cho hoạt động mà bạn không muốn giữ trên ngăn xếp.


có bất kỳ sự khác biệt nào so với việc bắt đầu hoạt động với cờ no_history không?
realtebo

1
Giống như bạn đã nói trong câu hỏi của mình "mọi lần mở danh sách KHÔNG được lưu vào 'lịch sử'" Vì vậy, bất cứ khi nào bạn mở lại ứng dụng của mình, điều đó sẽ đưa bạn đến hoạt động chính
Marcin S.

@MarcinS. khi ứng dụng không có trong danh sách ứng dụng gần đây, nó không hoạt động. Bạn có thể vui lòng giải thích về lý do tại sao điều này xảy ra không
Ajit Kumar Dubey

1
Vậy sự khác biệt giữa 2 cách tiếp cận đó (tệp kê khai và cờ) là gì?
pumbosha

@pumbosha Phương pháp tiếp cận Tệp kê khai sẽ luôn loại bỏ hoạt động ra khỏi lịch sử. Phương pháp cờ cho phép bạn kiểm soát hành vi đó trong thời gian chạy.
John Crawford

27

Sử dụng nhiệm vụ mới với xóa. Điều này hoạt động trong trường hợp của tôi khi các tùy chọn khác không.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Xóa toàn bộ ngăn xếp lịch sử và bắt đầu một hoạt động mới trên Android


1
Điều này sẽ rất tuyệt, nhưng có cách nào để dừng hoạt ảnh "thay đổi nhiệm vụ" của hệ thống không? Rất tiếc, việc thêm FLAG_ACTIVITY_NO_ANIMATION không ngăn được điều đó!
androidguy

điều này ảnh hưởng đến tốc độ ứng dụng?
Acauã Pitta

23

Có vẻ như, nếu bạn gọi finish () trên hoạt động của mình ngay sau khi bạn mở một hoạt động khác, thì hoạt động đã kết thúc sẽ bị xóa khỏi ngăn xếp.

ví dụ:

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

Nếu điện thoại của bạn chạy không quá nhanh, bạn sẽ thấy hoạt động trước đó đang ngừng hoạt động.
Nolan

@Nolan đó là chỉ khi bạn hoàn thành trước khi bắt đầu hoạt động
Henrik Bøgelund Lavstsen

7

Trong trường hợp cụ thể của tôi FLAG_ACTIVITY_NO_HISTORYđã không hoạt động. Không FLAG_ACTIVITY_NEW_TASKhoặc FLAG_ACTIVITY_CLEAR_TASKmột mình họ làm việc.

Tuy nhiên FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASKcùng nhau đã làm việc.

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

3

Chỉ muốn thêm một cách để thực hiện việc này trong Kotlin:

val i = Intent(this, LogInActivity::class.java)
startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK))

2
Thêm một cách Kotlin: Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) }.also { startActivity(it) }
4ndro1

3

Câu trả lời muộn, nhưng thêm một số chiều sâu cho các câu trả lời khác. Tất cả là do bạn muốn điều gì xảy ra với các hoạt động khác bắt đầu từ hoạt động đó

Tùy chọn 1 - Chỉ một hoạt động này sẽ không có lịch sử hoạt động gọi điện

Sau đó, chỉ cần làm:

Intent i = new Intent(...);
i.addFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

Tùy chọn 2 - Tất cả các hoạt động bắt đầu từ hoạt động cụ thể đó không được có lịch sử

Sau đó, thêm vào tệp kê khai của hoạt động gọi:

android:noHistory="true" 

Nhưng nếu bạn muốn có lịch sử trong hoạt động mới, thì bạn phải xóa cờ theo cách thủ công:

Intent i = new Intent(...);
i.removeFlag(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);

Hy vọng rằng rõ ràng các câu trả lời khác :)


2

Hãy thử FLAG_ACTIVITY_CLEAR_TOP nếu hoạt động đã chạy:

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


-4

Bạn có thể không ghi đè nút quay lại trên hoạt động cụ thể để dừng chức năng 'quay lại' không?

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {

        return true;
    }
    return super.onKeyDown(keyCode, event);
}

6
Đừng làm điều này. Có thể chấp nhận việc chặn BACK cho các mục đích cụ thể nhưng làm điều đó hoàn toàn là để tiêu thụ báo chí BACK một cách âm thầm và ngăn chặn việc chấm dứt một Activityhành động không tốt.
Squonk

1
Đồng ý hoàn toàn ^ chỉ là một lựa chọn.
Broak

1
OnBackPressedcho điều đó.
Fred
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.