Làm cách nào để bạn sử dụng Intent.FLAG_ACTIVITY_CLEAR_TOP để xóa Ngăn xếp hoạt động?


84

Tôi đã đọc qua một số bài viết về việc sử dụng cái này, nhưng phải thiếu một cái gì đó vì nó không hoạt động với tôi. Hoạt động A của tôi có Launcmode = "singleTop" trong tệp kê khai. Nó bắt đầu hoạt động B, với launcmode = "singleInstance". Hoạt động B mở một trình duyệt và nhận và có ý định trở lại, đó là lý do tại sao nó là singleInstance. Tôi đang cố gắng ghi đè nút quay lại để người dùng được đưa trở lại hoạt động A và sau đó có thể nhấn Quay lại để rời khỏi hoạt động, thay vì quay lại hoạt động B một lần nữa.

// activity B
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
  && keyCode == KeyEvent.KEYCODE_BACK
  && event.getRepeatCount() == 0) onBackPressed();
 return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
 startActivity(new Intent(this, UI.class)
 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
 return;
}

Sau khi quay lại từ trình duyệt, ngăn xếp là ... A, B, Trình duyệt, B

Tôi hy vọng mã này sẽ thay đổi ngăn xếp thành ... A ... để việc nhấn lại một lần nữa sẽ đưa người dùng trở lại Màn hình chính.

Thay vào đó, nó dường như thay đổi ngăn xếp thành ... A, B, Trình duyệt, B, A ... như thể những cờ đó không có ở đó.

Tôi đã thử gọi finish () trong hoạt động B sau startActivity, nhưng sau đó nút quay lại đưa tôi quay lại trình duyệt một lần nữa!

Tôi đang thiếu gì? Cảm ơn bạn!

Câu trả lời:


72

@bitestar có giải pháp chính xác, nhưng còn một bước nữa:

Nó được ẩn đi trong các tài liệu, tuy nhiên bạn phải thay đổi launchModecủa Activitybất cứ điều gì khác hơn standard. Nếu không, nó sẽ bị phá hủy và tạo lại thay vì được đặt lại lên đầu.


51
Trên thực tế ... Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPsẽ làm điều đó.
Derk-Jan

Kiểm tra giải pháp của Steel_fedex để làm ví dụ.
Darpan

2
vậy giải pháp của Steel_fedex ở đâu ?!
ChangWon Jeong Juicycool

112

Tôi đã bắt đầu Hoạt động A-> B-> C-> D. Khi nhấn nút quay lại trên Hoạt động DI muốn chuyển đến Hoạt động A. Vì A là điểm bắt đầu của tôi và do đó đã có trong ngăn xếp nên tất cả các hoạt động ở đầu A sẽ bị xóa và bạn không thể quay lại bất kỳ Hoạt động nào khác từ A .

Điều này thực sự hoạt động trong mã của tôi:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent a = new Intent(this,A.class);
        a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(a);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}       

4
Giải pháp này là đóng tất cả các hoạt động trung gian; mà còn, khởi động lại RootActivity. Bạn có thể kiểm tra giải pháp của @ Steel_Fedex bên dưới. Nó thực hiện tương tự, nhưng không khởi động lại RootActivity.
Darpan

Đây là giải pháp tốt nhất cho trường hợp của tôi. Tôi thực sự muốn các hoạt động gốc để bắt đầu lên một lần nữa
Tash Pemhiwa

24

Đối với điều này, tôi sử dụng FLAG_ACTIVITY_CLEAR_TOPcờ để bắt đầu Intent
(không có FLAG_ACTIVITY_NEW_TASK)

launchMode = "singleTask"trong tệp kê khai cho hoạt động đã khởi chạy.

Có vẻ như nó hoạt động như tôi cần - hoạt động không khởi động lại và tất cả các hoạt động khác đều bị đóng.


Tôi đã kiểm tra, Giải pháp của Bitster không hoạt động. Trong khi giải pháp này hoạt động. RootActivity không khởi động lại.
Darpan

Chọn từ ngữ của bạn một cách khôn ngoan hơn. Giải pháp Bitestar thực sự hoạt động!
Jesper Bischoff-Jensen

singleTask phù hợp với tôi, vì vậy Activity sẽ không tạo lại và xử lý sự kiện trong onNewIntent.
Jishi Chen

11

Mặc dù câu hỏi này đã có đầy đủ câu trả lời, tôi nghĩ ai đó sẽ muốn biết tại sao lá cờ này hoạt động theo cách đặc biệt này, Đây là những gì tôi tìm thấy trong tài liệu Android

Phiên bản hiện đang chạy của hoạt động B trong ví dụ trên sẽ nhận được ý định mới mà bạn đang bắt đầu ở đây trong phương thức onNewIntent () của nó hoặc được hoàn thành và khởi động lại với ý định mới.

Nếu nó đã tuyên bố chế độ khởi chạy của nó là "nhiều" (mặc định) và bạn không đặt FLAG_ACTIVITY_SINGLE_TOP theo cùng một mục đích, thì nó sẽ được hoàn thành và được tạo lại; cho tất cả các chế độ khởi chạy khác hoặc nếu FLAG_ACTIVITY_SINGLE_TOP được đặt thì Ý định này sẽ được chuyển đến onNewIntent () của phiên bản hiện tại.


Vì vậy, Hoặc,
1 . Thay đổi launchModeHoạt động A thành một thứ khác so với tiêu chuẩn (tức là. singleTaskHoặc một cái gì đó). Sau đó, cờ của bạn FLAG_ACTIVITY_CLEAR_TOPsẽ không khởi động lại Hoạt động A của bạn.

hoặc là,

2 . Sử dụng Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPlàm cờ của bạn. Sau đó, nó sẽ hoạt động theo cách bạn mong muốn.


8

Tôi sử dụng ba cờ để giải quyết vấn đề:

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

4

Thêm android: noHistory = "true" vào tệp kê khai.

<manifest >
        <activity
            android:name="UI"
            android:noHistory="true"/>

</manifest>

Lần đầu tiên nhìn thấy lá cờ này, nhưng nó làm việc cho trường hợp của tôi, nhờ
vlasentiy

3

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

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Nhưng nó sẽ không hoạt động với tôi ... Tôi không đề xuất giải pháp này để sử dụng nhưng nếu thiết lập cờ không phù hợp với bạn thì bạn có thể thử cách này..Nhưng tôi vẫn khuyên bạn không nên sử dụng nó


2

Tôi biết rằng đã có một câu trả lời được chấp nhận, nhưng tôi không biết nó hoạt động như thế nào đối với OP vì tôi không nghĩ FLAG_ACTIVITY_CLEAR_TOP có ý nghĩa trong trường hợp cụ thể của anh ấy. Cờ đó chỉ có liên quan với các hoạt động trong cùng một nhiệm vụ . Dựa trên mô tả của anh ấy, mỗi hoạt động có nhiệm vụ riêng : A, B và trình duyệt.

Điều gì đó có thể khiến anh ta khó chịu là A là singleTop, khi nó phải là singleTask. Nếu A là singleTop và B bắt đầu A, thì A mới sẽ được tạo vì A không thuộc nhiệm vụ của B. Từ tài liệu cho singleTop:

"Nếu một phiên bản của hoạt động đã tồn tại ở đầu tác vụ hiện tại , hệ thống sẽ định tuyến ý định đến phiên bản đó ..."

Vì B bắt đầu A, nhiệm vụ hiện tại là nhiệm vụ của B, là nhiệm vụ cho một SingleInstance và do đó không thể bao gồm A. Sử dụng singleTask để đạt được kết quả mong muốn ở đó vì sau đó hệ thống sẽ tìm nhiệm vụ có A và đưa nhiệm vụ đó lên tiền cảnh.

Cuối cùng, sau khi B bắt đầu A và người dùng nhấn trở lại từ A, OP không muốn nhìn thấy B hoặc trình duyệt. Để đạt được điều này, gọi finish () trong B là đúng; một lần nữa, FLAG_ACTIVITY_CLEAR_TOP sẽ không xóa các hoạt động khác trong nhiệm vụ của A vì các hoạt động khác của anh ấy đều thuộc các nhiệm vụ khác nhau. Tuy nhiên, phần mà anh ta còn thiếu là B cũng nên sử dụng FLAG_ACTIVITY_NO_HISTORY khi kích hoạt ý định cho trình duyệt. Lưu ý: nếu trình duyệt đã chạy trước khi thậm chí khởi động ứng dụng OP, thì tất nhiên bạn sẽ thấy trình duyệt khi nhấn trở lại từ A. Vì vậy, để thực sự kiểm tra điều này, hãy đảm bảo thoát khỏi trình duyệt trước khi khởi động ứng dụng.


1

FLAG_ACTIVITY_NEW_TASK là sự cố ở đây bắt đầu một tác vụ mới. Chỉ cần xóa nó là xong.

Tôi khuyên bạn nên đọc những gì mọi Cờ làm trước khi làm việc với họ

Đọc cái này & Cờ ý định ở đây


1
Tôi đã đọc lá cờ, và nó giống như những gì tôi cần. Bất kể, việc xóa FLAG_ACTIVITY_NEW_TASK không ảnh hưởng đến kết quả. Nó vẫn là vô tận nút quay lại vòng lặp ... A-> B, trở lại A, B trở lại, trở lại A ...
piusvelte

Bạn có chắc chắn tại sao mình đang sử dụng B làm singleInstance không? Hoạt động AA "singleInstance" hoạt động như thể FLAG_ACTIVITY_NEW_TASK là có ý định. Kiểm tra developer.android.com/guide/topics/fundamentals.html
100rabh

B cần nhận được ý định được gọi lại từ trình duyệt. Tôi đã thử thay đổi chế độ khởi chạy thành singleTask và điều đó vẫn hoạt động, nhưng vòng lặp nút quay lại vẫn xảy ra.
piusvelte

tôi nghĩ nó không hoạt động vì bạn đã sử dụng FLAG_ACTIVITY_NEW_TASK ở đó. Tốt hơn chỉ nên sử dụng FLAG_ACTIVITY_CLEAR_TOP và tránh sử dụng singleTask hay singleInstance
100rabh

1
Tôi nghĩ rằng phải là một giải pháp làm việc, nếu bạn thêm Intent.FLAG_ACTIVITY_SINGLE_TOPđể ngăn chặn sự tái tạo
yonojoy

1

Ban đầu, tôi cũng gặp sự cố khi FLAG_ACTIVITY_CLEAR_TOP hoạt động. Cuối cùng tôi đã làm cho nó hoạt động bằng cách sử dụng giá trị của nó (0x04000000). Vì vậy, có vẻ như có một vấn đề về Eclipse / trình biên dịch. Nhưng không may là hoạt động sống sót được khởi động lại, đó không phải là điều tôi muốn. Vì vậy, có vẻ như không có giải pháp dễ dàng.

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.