Question

Call a Method After a Delay in Android Java

javaandroidhandlerdelay

Question

How can I call a Java method in an Android app after a specified delay? In Objective-C, I could use performSelector:withObject:afterDelay::

[self performSelector:@selector(doSomething) withObject:nil afterDelay:5];

What is the Android Java equivalent if I need to call a method such as doSomething() after five seconds?

public void doSomething() {
    // Do something here.
}

Short Answer

You will learn how to schedule code to run later in an Android Java app with Handler.postDelayed(). You will also learn why delayed work is usually posted to the main thread, how to cancel it, and how to avoid updating a screen after its Activity has been destroyed.

Concept

Android does not use Objective-C's performSelector:withObject:afterDelay: API. In Java-based Android apps, a common equivalent is a Handler and its postDelayed() method.

A Handler places a Runnable—a piece of code to run—onto a thread's message queue. postDelayed() adds that work to the queue but tells Android not to run it until the requested delay has passed.

For UI-related work, create the handler with Looper.getMainLooper(). This posts the work to Android's main thread, which is the thread allowed to update views such as TextView, Button, and RecyclerView.

Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(() -> doSomething(), 5_000);

The delay is measured in milliseconds, so 5_000 means five seconds.

A delay is not a guarantee of exact timing. Android will run the task no earlier than the requested delay when the target thread is able to process it. If the main thread is busy, the callback can happen later.

Mental Model

Think of a Handler as a receptionist with a timed appointment book.

  • A Runnable is an instruction card: “run doSomething().”
  • postDelayed() gives the receptionist the card and says: “do not hand this to the main thread for 5 seconds.”
  • After the time passes, the main thread receives the card when it is free.
  • removeCallbacks() takes the card back before it is delivered.

This is useful when an action should happen later, but you may no longer need it if the user leaves the screen.

Take Quiz

Syntax and Examples

Create a Handler for the main thread, then post a Runnable with a delay in milliseconds.

import android.os.Handler;
import android.os.Looper;

Handler handler = new Handler(Looper.getMainLooper());

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        doSomething();
    }
}, 5_000);

With Java 8 language support enabled in an Android project, the same code can be shorter with a lambda:

handler.postDelayed(() -> doSomething(), 5_000);

For example, this changes a message after two seconds:

TextView statusText = findViewById(R.id.status_text);
Handler handler = new Handler(Looper.getMainLooper());

statusText.setText("Waiting...");

handler.postDelayed(() -> {
    statusText.setText("Finished");
}, 2_000);

The lambda does not run immediately. Android stores it in the main thread's queue and runs it after at least 2,000 milliseconds.

Step by Step Execution

Consider this code:

Handler handler = new Handler(Looper.getMainLooper());

handler.postDelayed(() -> {
    doSomething();
}, 5_000);
  1. new Handler(Looper.getMainLooper()) creates a handler associated with the UI thread.
  2. postDelayed(...) receives the lambda and the delay value 5_000.
  3. Android adds the lambda to the main thread's message queue with a future execution time.
  4. The current method continues immediately; it does not pause for five seconds.
  5. After at least five seconds, Android checks the main thread's queue.
  6. When the main thread is available, it runs the lambda.
  7. The lambda calls doSomething().
private void doSomething() {
    Log.d("DelayExample", "Five seconds have passed");
}

If the UI thread is blocked by expensive work, step 6 occurs later. Keep UI-thread callbacks short.

Real World Use Cases

Delayed callbacks are useful for small, UI-oriented tasks such as:

  • Splash or onboarding transitions: show an introductory message briefly before revealing the next screen.
  • Search input debouncing: wait briefly after the user stops typing before requesting search results.
  • Temporary feedback: hide a success message or undo bar after a few seconds.
  • Button protection: re-enable a button after a short cooldown.
  • Animations and UI sequencing: start a second UI change after the first one has had time to appear.
  • Retry timing: schedule a lightweight retry after a short wait, while still considering lifecycle and network requirements.

For work that must continue reliably after the user closes the app or after a device restart, a simple Handler is usually not the correct tool. Use an Android scheduling API designed for persistent background work, such as WorkManager, when appropriate.

Take Quiz

Real Codebase Usage

In production code, developers usually keep a reference to the delayed Runnable. This makes cancellation possible and prevents an old screen from being updated later.

private final Handler handler = new Handler(Looper.getMainLooper());

private final Runnable showResultRunnable = () -> {
    showResult();
};

private void scheduleResult() {
    handler.postDelayed(showResultRunnable, 5_000);
}

private void cancelScheduledResult() {
    handler.removeCallbacks(showResultRunnable);
}

A common Activity pattern is to cancel callbacks when the activity is being destroyed:

@Override
protected void onDestroy() {
    handler.removeCallbacks(showResultRunnable);
    super.onDestroy();
}

For a search field, cancel the previous request before scheduling a new one. This is a debounce pattern:

private void onQueryChanged(String query) {
    handler.removeCallbacks(searchRunnable);
    searchRunnable = () -> search(query);
    handler.postDelayed(searchRunnable, 300);
}

In practice, make searchRunnable a field and carefully manage it. The important pattern is: remove the old pending callback, then schedule the latest one.

Use a delayed handler callback for short-lived UI timing. Do not use Thread.sleep() on the main thread; it freezes the interface and prevents taps, drawing, and queued callbacks from being processed.

Common Mistakes

Treating seconds as milliseconds

postDelayed() expects milliseconds.

// Wrong: this delays for 5 milliseconds, not 5 seconds.
handler.postDelayed(() -> doSomething(), 5);

// Correct
handler.postDelayed(() -> doSomething(), 5_000);

Blocking the main thread with Thread.sleep()

// Wrong when called on the Android UI thread.
Thread.sleep(5_000);
doSomething();

This freezes the UI for five seconds. Schedule the callback instead:

handler.postDelayed(() -> doSomething(), 5_000);

Updating a view from a background thread

Android views must be changed on the main thread. If code is running on a background executor, use a main-thread handler for the UI update:

new Handler(Looper.getMainLooper()).postDelayed(() -> {
    statusText.setText("Done");
}, 5_000);

Forgetting to cancel an outdated callback

A user may leave the screen before the delay ends. If the callback uses that screen's views, cancel it during the appropriate lifecycle event:

handler.removeCallbacks(delayedRunnable);

Expecting exact timing

A five-second delay means “run no earlier than roughly five seconds when the thread can handle it.” It is not a real-time timer. Avoid using it for precise timing or persistent scheduled jobs.

Comparisons

ApproachBest forImportant behavior
Handler.postDelayed()Short UI delays and main-thread callbacksRuns on the handler's looper; can be cancelled with removeCallbacks()
View.postDelayed()A delay directly associated with one viewConvenient for view-related code; still cancel or account for lifecycle when needed
Thread.sleep()Pausing a background thread onlyBlocks that thread; never sleep on the UI thread
Timer / TimerTaskOlder Java timer-style codeUsually less convenient for Android UI work because UI updates still need the main thread
WorkManagerDeferrable background work that should survive app exitsNot intended for an exact five-second UI delay

View.postDelayed() can be concise when you already have a view:

statusText.postDelayed(() -> statusText.setText("Done"), 5_000);

For code that is not specifically owned by a view, a Handler makes the target thread explicit.

Take Quiz

Cheat Sheet

// Imports
import android.os.Handler;
import android.os.Looper;

// Main-thread handler
Handler handler = new Handler(Looper.getMainLooper());

// Run once after 5 seconds
handler.postDelayed(() -> doSomething(), 5_000);

// Keep a Runnable reference when it may need cancellation
Runnable task = () -> doSomething();
handler.postDelayed(task, 5_000);

// Cancel that pending task
handler.removeCallbacks(task);
  • postDelayed(runnable, delayMillis) uses milliseconds.
  • 1_000 ms = 1 second.
  • A main-looper handler can safely update Android views.
  • The calling method continues immediately after scheduling.
  • Delays can run late if the target thread is busy.
  • Cancel callbacks that are no longer valid, especially when a screen is closed.
  • Do not call Thread.sleep() on the main thread.

FAQ

What is the Android Java equivalent of performSelector:afterDelay:?

For common UI work, use Handler.postDelayed() with a Runnable:

new Handler(Looper.getMainLooper()).postDelayed(() -> doSomething(), 5_000);

Is the delay value in seconds?

No. postDelayed() uses milliseconds. Use 5_000 for five seconds.

Does postDelayed() block the current method?

No. It schedules work for later and returns immediately.

Can I update a TextView in a delayed callback?

Yes, when the callback is posted through a handler associated with Looper.getMainLooper() or through view.postDelayed().

How do I cancel a delayed method call in Android?

Keep the same Runnable instance and pass it to removeCallbacks():

handler.removeCallbacks(task);

Why did my delayed callback run after I left the screen?

It remained queued. Cancel it when the action is no longer relevant, such as in onDestroy() for an activity-owned callback.

Is Handler.postDelayed() suitable for background jobs that must run later?

Not usually. It is appropriate for short-lived in-app timing. Use a persistent Android work scheduling solution, such as WorkManager, for work that should survive app closure or process death.

Take Quiz

Mini Project

Description

Build a small delayed status screen. When the user taps a button, the app shows a waiting message and schedules a completion message for five seconds later. If the activity is destroyed before the delay ends, the pending callback is cancelled.

Goal

Use Handler.postDelayed() to update an Android TextView after five seconds without blocking the UI.

Requirements

Create an activity with a status TextView and a start Button.

Take Quiz

Keep learning

Related questions

View more