класс - handler thread java




Как вызвать метод после задержки в Android (16)

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

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

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

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

Вот еще один сложный способ: он не будет генерировать исключение, когда элементы пользовательского интерфейса с изменяемым изменением.

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

    }
}

Вы можете вызвать анимацию следующим образом:

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

Анимация может быть прикреплена к любому виду.


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

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

Вы можете сделать его более чистым, используя недавно введенные лямбда-выражения:

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

Если вам нужно использовать Handler, но вы используете другой поток, вы можете использовать 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);
    }
});

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


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

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

Лучшая версия:

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

Ниже один работает, когда вы получаете,

java.lang.RuntimeException: невозможно создать обработчик внутри потока, который не вызвал Looper.prepare ()

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

Подходящее решение в 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
        }
    }

См. Эту демонстрацию:

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?");
     }
}

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

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
    }
}

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

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

Я предлагаю Timer , он позволяет планировать метод, который будет вызываться на очень определенном интервале. Это не будет блокировать ваш пользовательский интерфейс и не будет поддерживать ваше приложение во время выполнения метода.

Другой вариант - wait(); метод, это заблокирует текущий поток за указанный период времени. Это приведет к тому, что ваш пользовательский интерфейс перестанет отвечать на запросы, если вы это сделаете в потоке пользовательского интерфейса.


Я создал более простой способ назвать это.

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

Чтобы использовать его, просто позвоните: .CallWithDelay(5000, this, "DoSomething");


все, кажется, забывают очистить обработчик, прежде чем публиковать на нем новую версию или сообщение. В противном случае они могут потенциально накапливаться и вызывать плохое поведение.

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.

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

Похоже, что Mac OS API позволяет текущему потоку продолжать работу и планирует запуск асинхронной задачи. В 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);
  ⋮
}

Вот ответ в Котлин вам ленивые, ленивые люди:

Handler().postDelayed({
//doSomethingHere()
}, 1000)






delay