Как вызвать метод после задержки в Android - PullRequest
681 голосов
/ 18 июня 2010

Я хочу иметь возможность вызывать следующий метод после указанной задержки. В цели c было что-то вроде:

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

Есть ли эквивалент этого метода в Android с Java? Например, мне нужно иметь возможность вызывать метод через 5 секунд.

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

Ответы [ 31 ]

1673 голосов
/ 06 февраля 2012

Котлин

Handler().postDelayed({
  //Do something after 100ms
}, 100)


Java

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


293 голосов
/ 23 июня 2012

Я не мог использовать другие ответы в моем случае. Вместо этого я использовал нативный таймер Java.

new Timer().schedule(new TimerTask() {          
    @Override
    public void run() {
        // this code will be executed after 2 seconds       
    }
}, 2000);
180 голосов
/ 18 июня 2010

Примечание: Этот ответ был дан, когда в вопросе не указан Android в качестве контекста. Для ответа, относящегося к теме пользовательского интерфейса Android , посмотрите здесь.


Похоже, что API Mac OS позволяет текущему потоку продолжить и планирует выполнение задачи асинхронно. В Java эквивалентная функция предоставляется пакетом java.util.concurrent. Я не уверен, какие ограничения может наложить 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);
  ⋮
}
95 голосов
/ 27 января 2015

Для выполнения чего-либо в потоке пользовательского интерфейса через 5 секунд:

new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something here
    }
}, 5000);
38 голосов
/ 22 марта 2013

вы можете использовать обработчик внутри UIThread:

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);

    }
});
36 голосов
/ 18 июня 2010

Спасибо за все отличные ответы, я нашел решение, которое наилучшим образом соответствует моим потребностям.

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
    }
}
21 голосов
/ 04 февраля 2015

Если вам нужно использовать обработчик, но вы находитесь в другом потоке, вы можете использовать runonuithread для запуска обработчика в потоке пользовательского интерфейса. Это избавит вас от исключений, брошенных с просьбой позвонить Looper.Prepare()

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

выглядит довольно грязно, но это один из способов.

20 голосов
/ 18 июня 2010

Посмотрите эту демонстрацию:

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?");
     }
}
16 голосов
/ 14 мая 2015

Я предпочитаю использовать View.postDelayed() метод, простой код ниже:

mView.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 1000 ms
    }
}, 1000);
14 голосов
/ 29 января 2017

Вот мое самое короткое решение:

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