在Android中延迟后如何调用方法

时间:2022-09-06 01:17:35

I want to be able to call the following method after a specified delay. In objective c there was something like:

我希望能够在指定的延迟之后调用以下方法。在objective c中有如下内容:

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

Is there an equivalent of this method in android with java? For example I need to be able to call a method after 5 seconds.

安卓中是否有与java类似的方法?例如,我需要能够在5秒后调用一个方法。

public void DoSomething()
{
     //do something here
}

20 个解决方案

#1


1437  

Better version:

更好的版本:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);

#2


256  

I couldn't use any of the other answers in my case. I used the native java Timer instead.

我不能用其他答案来回答我的问题。我使用的是本机java计时器。

new Timer().schedule(new TimerTask() {          
    @Override
    public void run() {
        // this code will be executed after 2 seconds       
    }
}, 2000);

#3


177  

Note: This answer was given when the question didn't specify Android as the context. For an answer specific to the Android UI thread look here.

注意:当问题没有指定Android作为上下文时,给出了这个答案。对于特定于Android UI线程的答案,请参见这里。


It looks like the Mac OS API lets the current thread continue, and schedules the task to run asynchronously. In the Java, the equivalent function is provided by the java.util.concurrent package. I'm not sure what limitations Android might impose.

看起来Mac OS API允许当前线程继续运行,并将任务安排为异步运行。在Java中,等价函数由Java .util提供。并发包。我不确定Android会有什么限制。

private static final ScheduledExecutorService worker = 
  Executors.newSingleThreadScheduledExecutor();

void someMethod() {
  ⋮
  Runnable task = new Runnable() {
    public void run() {
      /* Do something… */
    }
  };
  worker.schedule(task, 5, TimeUnit.SECONDS);
  ⋮
}

#4


89  

For executing something in the UI Thread after 5 seconds:

5秒后在UI线程中执行某事:

new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something here
    }
}, 5000);

#5


35  

you can use Handler inside UIThread:

你可以在UIThread内部使用Handler:

runOnUiThread(new Runnable() {

    @Override
    public void run() {
         final Handler handler = new Handler();
         handler.postDelayed(new Runnable() {
           @Override
           public void run() {
               //add your code here
           }
         }, 1000);

    }
});

#6


34  

Thanks for all the great answers, I found a solution that best suits my needs.

谢谢你的回答,我找到了最适合我需要的解决方案。

Handler myHandler = new DoSomething();
Message m = new Message();
m.obj = c;//passing a parameter here
myHandler.sendMessageDelayed(m, 1000);

class DoSomething extends Handler {
    @Override
    public void handleMessage(Message msg) {
      MyObject o = (MyObject) msg.obj;
      //do something here
    }
}

#7


19  

If you have to use the Handler, but you are into another thread, you can use runonuithread to run the handler in UI thread. This will save you from Exceptions thrown asking to call Looper.Prepare()

如果您必须使用处理程序,但是您进入了另一个线程,您可以使用runonuithread在UI线程中运行处理程序。这将使您避免请求调用Looper.Prepare()的异常。

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 1 second
            }
        }, 1000);
    }
});

Looks quite messy, but this is one of the way.

看起来很乱,但这是其中之一。

#8


18  

See this demo:

看到这个演示:

import java.util.Timer;
import java.util.TimerTask;

class Test {
     public static void main( String [] args ) {
          int delay = 5000;// in ms 

          Timer timer = new Timer();

          timer.schedule( new TimerTask(){
             public void run() { 
                 System.out.println("Wait, what..:");
              }
           }, delay);

           System.out.println("Would it run?");
     }
}

#9


14  

I prefer to use View.postDelayed() method, simple code below:

我更喜欢使用view . postdelay()方法,简单代码如下:

mView.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 1000 ms
    }
}, 1000);

#10


11  

Here is my shortest solution:

这是我最简短的解决办法:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something after 100ms
    }
}, 100);

#11


10  

final Handler handler = new Handler(); 
Timer t = new Timer(); 
t.schedule(new TimerTask() { 
    public void run() { 
        handler.post(new Runnable() { 
            public void run() { 
                //DO SOME ACTIONS HERE , THIS ACTIONS WILL WILL EXECUTE AFTER 5 SECONDS...
            }
        }); 
    } 
}, 5000); 

#12


5  

I suggest the Timer, it allows you to schedule a method to be called on a very specific interval. This will not block your UI, and keep your app resonsive while the method is being executed.

我建议使用计时器,它允许您安排一个方法在一个非常特定的间隔进行调用。这不会阻塞您的UI,并且在方法执行时保持应用程序的共振。

The other option, is the wait(); method, this will block the current thread for the specified length of time. This will cause your UI to stop responding if you do this on the UI thread.

另一个选项是wait();方法,这将阻塞当前线程的指定时间长度。如果在UI线程上这样做,将导致UI停止响应。

#13


5  

If you are using Android Studio 3.0 and above you can use lambda expressions. The method callMyMethod() is called after 2 seconds:

如果你使用的是Android Studio 3.0,你可以使用lambda表达式。2秒后调用方法callMyMethod():

new Handler().postDelayed(() -> callMyMethod(), 2000);

In case you need to cancel all the delayed runnables:

如果您需要取消所有延迟的runnables:

Handler handler = new Handler();
handler.postDelayed(() -> callMyMethod(), 2000);

// When you need to cancel all your posted runnables just use:
handler.removeCallbacksAndMessages(null);

#14


4  

You can use this for Simplest Solution:

您可以使用这个最简单的解决方案:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Write your code here
    }
}, 5000); //Timer is in ms here.

Else, Below can be another clean useful solution:

否则,下面是另一个干净有用的解决方案:

new Handler().postDelayed(() -> 
{/*Do something here*/}, 
5000); //time in ms

#15


3  

I created simpler method to call this.

我创建了更简单的方法来调用它。

public static void CallWithDelay(long miliseconds, final Activity activity, final String methodName)
    {
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                try {
                    Method method =  activity.getClass().getMethod(methodName);
                    method.invoke(activity);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }, miliseconds);
    }

To use it, just call : .CallWithDelay(5000, this, "DoSomething");

要使用它,只需调用:.CallWithDelay(5000,这个,“DoSomething”);

#16


2  

It's very easy using the CountDownTimer. For more details https://developer.android.com/reference/android/os/CountDownTimer.html

使用CountDownTimer很容易。更多细节https://developer.android.com/reference/android/os/CountDownTimer.html

import android.os.CountDownTimer;

// calls onTick every second, finishes after 3 seconds
new CountDownTimer(3000, 1000) { 

   public void onTick(long millisUntilFinished) {
      Log.d("log", millisUntilFinished / 1000);
   }

   public void onFinish() {
      // called after count down is finished
   } 
}.start();

#17


1  

Here is another tricky way: it won't throw exception when the runnable change UI elements.

还有一种巧妙的方法:当可运行的UI元素发生变化时,它不会抛出异常。

public class SimpleDelayAnimation extends Animation implements Animation.AnimationListener {

Runnable callBack;

public SimpleDelayAnimation(Runnable runnable, int delayTimeMilli) {
    setDuration(delayTimeMilli);
    callBack = runnable;
    setAnimationListener(this);
}

@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
    callBack.run();
}

@Override
public void onAnimationRepeat(Animation animation) {

}

}

}

You can call the animation like this:

你可以这样称呼动画:

    view.startAnimation(new SimpleDelayAnimation(delayRunnable, 500));

Animation can attach to any view.

动画可以附加到任何视图。

#18


1  

you can make it much cleaner by using the newly introduced lambda expressions:

您可以使用新引入的lambda表达式使其更简洁:

        new Handler().postDelayed(() -> {/*your code here*/}, time);

#19


1  

everybody seems to forget to clean the Handler before posting a new runnable or message on it. Otherway they could potentially accumulate and cause bad behaviour.

每个人似乎都忘记在发布新的runnable或消息之前清理处理程序。否则,它们可能会累积并导致不良行为。

handler.removeMessages(int what);
// Remove any pending posts of messages with code 'what' that are in the message queue.

handler.removeCallbacks(Runnable r)
// Remove any pending posts of Runnable r that are in the message queue.

#20


0  

A suitable solution in android:

android中合适的解决方案:

private static long SLEEP_TIME = 2 // for 2 second
.
.
MyLauncher launcher = new MyLauncher();
            launcher.start();
.
.
private class MyLauncher extends Thread {
        @Override
        /**
         * Sleep for 2 seconds as you can also change SLEEP_TIME 2 to any. 
         */
        public void run() {
            try {
                // Sleeping
                Thread.sleep(SLEEP_TIME * 1000);
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
            //do something you want to do
           //And your code will be executed after 2 second
        }
    }

#1


1437  

Better version:

更好的版本:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);

#2


256  

I couldn't use any of the other answers in my case. I used the native java Timer instead.

我不能用其他答案来回答我的问题。我使用的是本机java计时器。

new Timer().schedule(new TimerTask() {          
    @Override
    public void run() {
        // this code will be executed after 2 seconds       
    }
}, 2000);

#3


177  

Note: This answer was given when the question didn't specify Android as the context. For an answer specific to the Android UI thread look here.

注意:当问题没有指定Android作为上下文时,给出了这个答案。对于特定于Android UI线程的答案,请参见这里。


It looks like the Mac OS API lets the current thread continue, and schedules the task to run asynchronously. In the Java, the equivalent function is provided by the java.util.concurrent package. I'm not sure what limitations Android might impose.

看起来Mac OS API允许当前线程继续运行,并将任务安排为异步运行。在Java中,等价函数由Java .util提供。并发包。我不确定Android会有什么限制。

private static final ScheduledExecutorService worker = 
  Executors.newSingleThreadScheduledExecutor();

void someMethod() {
  ⋮
  Runnable task = new Runnable() {
    public void run() {
      /* Do something… */
    }
  };
  worker.schedule(task, 5, TimeUnit.SECONDS);
  ⋮
}

#4


89  

For executing something in the UI Thread after 5 seconds:

5秒后在UI线程中执行某事:

new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something here
    }
}, 5000);

#5


35  

you can use Handler inside UIThread:

你可以在UIThread内部使用Handler:

runOnUiThread(new Runnable() {

    @Override
    public void run() {
         final Handler handler = new Handler();
         handler.postDelayed(new Runnable() {
           @Override
           public void run() {
               //add your code here
           }
         }, 1000);

    }
});

#6


34  

Thanks for all the great answers, I found a solution that best suits my needs.

谢谢你的回答,我找到了最适合我需要的解决方案。

Handler myHandler = new DoSomething();
Message m = new Message();
m.obj = c;//passing a parameter here
myHandler.sendMessageDelayed(m, 1000);

class DoSomething extends Handler {
    @Override
    public void handleMessage(Message msg) {
      MyObject o = (MyObject) msg.obj;
      //do something here
    }
}

#7


19  

If you have to use the Handler, but you are into another thread, you can use runonuithread to run the handler in UI thread. This will save you from Exceptions thrown asking to call Looper.Prepare()

如果您必须使用处理程序,但是您进入了另一个线程,您可以使用runonuithread在UI线程中运行处理程序。这将使您避免请求调用Looper.Prepare()的异常。

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 1 second
            }
        }, 1000);
    }
});

Looks quite messy, but this is one of the way.

看起来很乱,但这是其中之一。

#8


18  

See this demo:

看到这个演示:

import java.util.Timer;
import java.util.TimerTask;

class Test {
     public static void main( String [] args ) {
          int delay = 5000;// in ms 

          Timer timer = new Timer();

          timer.schedule( new TimerTask(){
             public void run() { 
                 System.out.println("Wait, what..:");
              }
           }, delay);

           System.out.println("Would it run?");
     }
}

#9


14  

I prefer to use View.postDelayed() method, simple code below:

我更喜欢使用view . postdelay()方法,简单代码如下:

mView.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 1000 ms
    }
}, 1000);

#10


11  

Here is my shortest solution:

这是我最简短的解决办法:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something after 100ms
    }
}, 100);

#11


10  

final Handler handler = new Handler(); 
Timer t = new Timer(); 
t.schedule(new TimerTask() { 
    public void run() { 
        handler.post(new Runnable() { 
            public void run() { 
                //DO SOME ACTIONS HERE , THIS ACTIONS WILL WILL EXECUTE AFTER 5 SECONDS...
            }
        }); 
    } 
}, 5000); 

#12


5  

I suggest the Timer, it allows you to schedule a method to be called on a very specific interval. This will not block your UI, and keep your app resonsive while the method is being executed.

我建议使用计时器,它允许您安排一个方法在一个非常特定的间隔进行调用。这不会阻塞您的UI,并且在方法执行时保持应用程序的共振。

The other option, is the wait(); method, this will block the current thread for the specified length of time. This will cause your UI to stop responding if you do this on the UI thread.

另一个选项是wait();方法,这将阻塞当前线程的指定时间长度。如果在UI线程上这样做,将导致UI停止响应。

#13


5  

If you are using Android Studio 3.0 and above you can use lambda expressions. The method callMyMethod() is called after 2 seconds:

如果你使用的是Android Studio 3.0,你可以使用lambda表达式。2秒后调用方法callMyMethod():

new Handler().postDelayed(() -> callMyMethod(), 2000);

In case you need to cancel all the delayed runnables:

如果您需要取消所有延迟的runnables:

Handler handler = new Handler();
handler.postDelayed(() -> callMyMethod(), 2000);

// When you need to cancel all your posted runnables just use:
handler.removeCallbacksAndMessages(null);

#14


4  

You can use this for Simplest Solution:

您可以使用这个最简单的解决方案:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Write your code here
    }
}, 5000); //Timer is in ms here.

Else, Below can be another clean useful solution:

否则,下面是另一个干净有用的解决方案:

new Handler().postDelayed(() -> 
{/*Do something here*/}, 
5000); //time in ms

#15


3  

I created simpler method to call this.

我创建了更简单的方法来调用它。

public static void CallWithDelay(long miliseconds, final Activity activity, final String methodName)
    {
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                try {
                    Method method =  activity.getClass().getMethod(methodName);
                    method.invoke(activity);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }, miliseconds);
    }

To use it, just call : .CallWithDelay(5000, this, "DoSomething");

要使用它,只需调用:.CallWithDelay(5000,这个,“DoSomething”);

#16


2  

It's very easy using the CountDownTimer. For more details https://developer.android.com/reference/android/os/CountDownTimer.html

使用CountDownTimer很容易。更多细节https://developer.android.com/reference/android/os/CountDownTimer.html

import android.os.CountDownTimer;

// calls onTick every second, finishes after 3 seconds
new CountDownTimer(3000, 1000) { 

   public void onTick(long millisUntilFinished) {
      Log.d("log", millisUntilFinished / 1000);
   }

   public void onFinish() {
      // called after count down is finished
   } 
}.start();

#17


1  

Here is another tricky way: it won't throw exception when the runnable change UI elements.

还有一种巧妙的方法:当可运行的UI元素发生变化时,它不会抛出异常。

public class SimpleDelayAnimation extends Animation implements Animation.AnimationListener {

Runnable callBack;

public SimpleDelayAnimation(Runnable runnable, int delayTimeMilli) {
    setDuration(delayTimeMilli);
    callBack = runnable;
    setAnimationListener(this);
}

@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
    callBack.run();
}

@Override
public void onAnimationRepeat(Animation animation) {

}

}

}

You can call the animation like this:

你可以这样称呼动画:

    view.startAnimation(new SimpleDelayAnimation(delayRunnable, 500));

Animation can attach to any view.

动画可以附加到任何视图。

#18


1  

you can make it much cleaner by using the newly introduced lambda expressions:

您可以使用新引入的lambda表达式使其更简洁:

        new Handler().postDelayed(() -> {/*your code here*/}, time);

#19


1  

everybody seems to forget to clean the Handler before posting a new runnable or message on it. Otherway they could potentially accumulate and cause bad behaviour.

每个人似乎都忘记在发布新的runnable或消息之前清理处理程序。否则,它们可能会累积并导致不良行为。

handler.removeMessages(int what);
// Remove any pending posts of messages with code 'what' that are in the message queue.

handler.removeCallbacks(Runnable r)
// Remove any pending posts of Runnable r that are in the message queue.

#20


0  

A suitable solution in android:

android中合适的解决方案:

private static long SLEEP_TIME = 2 // for 2 second
.
.
MyLauncher launcher = new MyLauncher();
            launcher.start();
.
.
private class MyLauncher extends Thread {
        @Override
        /**
         * Sleep for 2 seconds as you can also change SLEEP_TIME 2 to any. 
         */
        public void run() {
            try {
                // Sleeping
                Thread.sleep(SLEEP_TIME * 1000);
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
            //do something you want to do
           //And your code will be executed after 2 second
        }
    }