hủy bỏ một quy trình handler.postdelayed


259

Tôi đang sử dụng handler.postDelayed()để tạo khoảng thời gian chờ đợi trước khi giai đoạn tiếp theo của ứng dụng của tôi diễn ra. Trong thời gian chờ đợi, tôi đang hiển thị một hộp thoại với thanh tiến trình và nút hủy .

Vấn đề của tôi là tôi không thể tìm cách hủy tác vụ đã bị hủy trước khi hết thời gian.



Hy vọng ý chính này giúp gist.github.com/imammubin/a587192982ff8db221da14d094df6fb4 MainActivity là Trình khởi chạy màn hình với chức năng xử lý & có thể chạy, Runnable chạy đến trang đăng nhập hoặc trang nguồn cấp dữ liệu với người dùng đăng nhập tùy chọn cơ sở với firebase.
Mubin

Câu trả lời:


479

Tôi làm điều này để đăng một runnable bị trì hoãn:

myHandler.postDelayed(myRunnable, SPLASH_DISPLAY_LENGTH); 

Và điều này để loại bỏ nó: myHandler.removeCallbacks(myRunnable);


74
Nếu bạn có thể đủ khả năng để hủy tất cả các cuộc gọi lại và tin nhắn trên trình xử lý và không muốn phải giữ các tham chiếu đến điểm có thể chạy được thì điểm thứ ba trong câu trả lời được chấp nhận cho câu hỏi này là một cách khác có vẻ phù hợp với trường hợp của tôi: stackoverflow. com / câu hỏi / 11299440 / Lỗi (về cơ bản gọi myHandler.removeCallbacksAndMessages (null);)
Mick

removeCallbacksAndMessages có thể thực hiện thủ thuật, nhưng cá nhân tôi thích có quyền kiểm soát các runnables theo lịch trình. Bắt đầu và xử lý một cặp Runnables sẽ không giết chết các màn trình diễn ứng dụng của bạn; mặt khác, nếu bạn cần nhiều hơn hai hoặc ba Runnables, bạn có thể cần thứ gì đó mạnh hơn, imho.
andrea.rinaldi

59

Trong trường hợp bạn có nhiều runnables bên trong / ẩn danh được chuyển đến cùng một trình xử lý và bạn muốn hủy tất cả tại cùng một sự kiện sử dụng

handler.removeCallbacksAndMessages(null);

Theo tài liệu,

Xóa mọi bài đăng đang chờ xử lý của các cuộc gọi lại và gửi tin nhắn có obj là mã thông báo. Nếu mã thông báo là null, tất cả các cuộc gọi lại và tin nhắn sẽ bị xóa.


Điều này sẽ loại bỏ tất cả các cuộc gọi lại có thể chạy một lần. Nếu không, hãy gọi removeCallbacks(callback) để xóa cuộc gọi lại cụ thể
FindOutIslamNow

18

Một cách khác là tự xử lý Runnable:

Runnable r = new Runnable {
    public void run() {
        if (booleanCancelMember != false) {
            //do what you need
        }
    }
}

14
Sẽ không boolean HủyMember phải là cuối cùng, có nghĩa là nó không thể thay đổi và do đó vô dụng cho mục đích này?
tàng hình

9
@stealthawaii không, không cần phải như vậy.
Benoit Jadinon

7
@pablisco Nó không phải là trận chung kết ngay cả khi Runnable là ẩn danh. Nó có thể là một thành viên trong lớp kèm theo.
Martin

6
Không hạ thấp điều này, nhưng hãy cẩn thận. Với phương pháp này, nếu nhiều Runnables được đăng bị trì hoãn, bạn có thể gặp tình trạng đua khó chịu. Điều này không hủy bỏ Runnable, do đó, mã đó sẽ được thực thi hay không phụ thuộc vào giá trị của boolean HủyMember tại thời điểm cụ thể cho mỗi Runnable được đăng. Mà có thể nhanh chóng trở nên khó lường.
Dennis K

1
Nếu Runnable KHÔNG có nghĩa là nó có nghĩa là tôi có một tài liệu tham khảo về nó ( rtrong trường hợp này) có nghĩa là tôi có thể sử dụng myHandler.removeCallbacks(r);. Nếu Runnable là ẩn danh thì cờ sẽ là thành viên trong lớp kèm theo, điều đó có nghĩa là tôi cần một tham chiếu đến đối tượng đó để thay đổi cờ, điều đó có nghĩa là tôi sẽ phải có mọi cách r, điều đó có nghĩa là tôi có thể làm được myHandler.removeCallbacks(r);. Và nếu tôi đang làm myHandler.removeCallbacks(r);thì cờ như vậy là không cần thiết. Tui bỏ lỡ điều gì vậy?
nacho4d

1

Đây là một lớp cung cấp một phương thức hủy bỏ cho một hành động bị trì hoãn

public class DelayedAction {

private Handler _handler;
private Runnable _runnable;

/**
 * Constructor
 * @param runnable The runnable
 * @param delay The delay (in milli sec) to wait before running the runnable
 */
public DelayedAction(Runnable runnable, long delay) {
    _handler = new Handler(Looper.getMainLooper());
    _runnable = runnable;
    _handler.postDelayed(_runnable, delay);
}

/**
 * Cancel a runnable
 */
public void cancel() {
    if ( _handler == null || _runnable == null ) {
        return;
    }
    _handler.removeCallbacks(_runnable);
}}

0

Nó hoạt động với tôi khi tôi gọi CancCallBacks (cái này) bên trong bài đăng bị trì hoãn bằng cách đưa nó qua boolean

Runnable runnable = new Runnable(){
    @Override
    public void run() {
        Log.e("HANDLER", "run: Outside Runnable");
        if (IsRecording) {
            Log.e("HANDLER", "run: Runnable");
            handler.postDelayed(this, 2000);
        }else{
            handler.removeCallbacks(this);
        }
    }
};

3
Không có "CancCallBacks" trong mã của bạn. Có lẽ vì nó không tồn tại? :)
Ngày 1

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.