Как заставить Android-программу "ждать"

Я хочу, чтобы моя программа приостанавливалась на определенное количество миллисекунд, как именно мне это сделать?

Я нашел разные способы, такие как Thread.sleep( time )Но я не думаю, что это то, что мне нужно. Я просто хочу, чтобы мой код останавливался на определенной строке на х миллисекунд. Любые идеи очень приветствуются.

Это оригинальный код на C...

extern void delay(UInt32 wait){
    UInt32 ticks;
    UInt32  pause;

    ticks = TimGetTicks();
    //use = ticks + (wait/4);
    pause = ticks + (wait);
    while(ticks < pause)
        ticks = TimGetTicks();
}

ожидание это количество миллисекунд

8 ответов

Решение

Хорошо, во-первых, никогда не выполняйте задержку с занятым циклом, как вы делаете. Я могу видеть, откуда это исходит - я предполагаю, что Palm Pilot был однопроцессным устройством без встроенной функции sleep(), но на многопроцессорном устройстве такой занятый цикл просто приносит весь процессор на колени. Он разряжает батарею, мешает нормальному выполнению системных задач, замедляет работу других программ или полностью их останавливает, приводит к тому, что устройство перестает отвечать на запросы и даже может нагреваться в ваших руках.

Вы ищете, это Thread.sleep(). Вам нужно настроить, чтобы перехватывать любые исключения прерываний, которые возникают во время сна.

Во-вторых, с пользовательскими интерфейсами, основанными на событиях, такими как Android (или почти любая современная система с графическим интерфейсом), вы никогда не захотите спать в потоке пользовательского интерфейса. Это также приведет к зависанию всего устройства и приведет к сбою ANR (активность не отвечает), как упоминали другие авторы. Самое главное, что эти небольшие зависания полностью разрушают пользовательский опыт.

(Исключение: если вы спите в течение достаточно коротких промежутков времени, которые пользователь, вероятно, не заметит, это может сойти с рук. Вероятно, 1/4 секунды - это нормально, хотя это может сделать приложение зависшим в зависимости от ситуации.)

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

Тем не менее, правильной процедурой является создание обработчика в вашем потоке пользовательского интерфейса и отправка ему отложенных сообщений. Отложенные сообщения "разбудят" ваше приложение и заставят его выполнить то, что он собирался сделать после задержки.

Что-то вроде этого:

View gameBoard;     // the view containing the main part of the game
int gameState = 0;  // starting
Handler myHandler;

public void onCreate(Bundle oldState) {
  super.onCreate(oldState);
  ...
  gameBoard = findViewById(R.layout.gameboard);
  myHandler = new Handler();
  ...
}

public void onResume() {
  super.onResume();
  displayStartingScreen();
  myHandler.postDelayed(new Runnable() { 
    gotoState1(); 
  }, 250);
}

private void gotoState1() {
  // It's now 1/4 second since onResume() was called
  displayNextScreen();
  myHandler.postDelayed(new Runnable() { 
    gotoState2();
  }, 250);
}
...

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

Если вы хотите отложить выполнение кода на определенное время, используйте Runnable и Handler, например:

Runnable r = new Runnable() {
    @Override
    public void run(){
        doSomething(); //<-- put your code in here.
    }
};

Handler h = new Handler();
h.postDelayed(r, 1000); // <-- the "1000" is the delay time in miliseconds. 

Таким образом, ваш код по-прежнему задерживается, но вы не "замораживаете" поток пользовательского интерфейса, что в лучшем случае приводит к низкой производительности, а к худшему - к ANR.

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

final MyActivity myActivity = this;   

    thread=  new Thread(){
        @Override
        public void run(){
            try {
                synchronized(this){
                    wait(3000);
                }
            }
            catch(InterruptedException ex){                    
            }

            // TODO              
        }
    };

    thread.start();   

Вы можете использовать Handler класс и postDelayed() способ сделать это:

Handler h =new Handler() ;

h.postDelayed(new Runnable() {

  public void run() {

    //put your code here

  }, 2000);

2000 мс - время задержки перед выполнением кода внутри функции

SystemClock.sleep(millis) - это служебная функция, очень похожая на Thread.sleep(millis), но она игнорирует InterruptedException.

Не уверен, почему вы хотите, чтобы программа приостановила. Если вы хотите выполнить какое-то задание в фоновом режиме и использовать результаты, посмотрите на AsyncTask. У меня был похожий вопрос некоторое время назад.

try {
    Thread.sleep(2000); //1000 milliseconds is one second.
}
catch (InterruptedException e) 
{
    e.printStackTrace();
}

Я думаю, что Thread.sleep (....), вероятно, то, что вы хотите, но вы можете делать это неправильно. Что именно вы пытаетесь сделать паузу? Надеюсь, не поток пользовательского интерфейса? Я предполагаю, что у вас есть какой-то фоновый поток, выполняющий некоторые задачи через определенный промежуток времени? Если это так, то Thread.sleep переведет этот конкретный поток в спящий режим на определенное время, однако он не остановит все потоки.

Другие вопросы по тегам