Как установить задержку в андроиде?

165
public void onClick(View v) {
        // TODO Auto-generated method stub
        switch(v.getId()){
        case R.id.rollDice:
            Random ranNum = new Random();
            int number = ranNum.nextInt(6) + 1;
            diceNum.setText(""+number);
            sum = sum + number;
            for(i=0;i<8;i++){
                for(j=0;j<8;j++){

                    int value =(Integer)buttons[i][j].getTag();
                    if(value==sum){
                        inew=i;
                        jnew=j;

                        buttons[inew][jnew].setBackgroundColor(Color.BLACK);
                                                //I want to insert a delay here
                        buttons[inew][jnew].setBackgroundColor(Color.WHITE);
                         break;                     
                    }
                }
            }


            break;

        }
    }

Я хочу установить задержку между командами между сменой фона. Я попытался использовать таймер потока и попытался использовать запустить и поймать. Но это не работает. Я пробовал это

 Thread timer = new Thread() {
            public void run(){
                try {
                                buttons[inew][jnew].setBackgroundColor(Color.BLACK);
                    sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

             }
           };
    timer.start();
   buttons[inew][jnew].setBackgroundColor(Color.WHITE);

Но это только становится черным.

Кеннет Джозеф Пол
источник

Ответы:

501

Попробуйте этот код:

import android.os.Handler;
...
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 5s = 5000ms
        buttons[inew][jnew].setBackgroundColor(Color.BLACK);
    }
}, 5000);
Туан Ву
источник
1
Это решение объяснило все вопросы, которые у меня были с обработчиками в некоторых строках кода.
Сиерисимо
45
Я всегда возвращаюсь к этому посту, потому что мне лень писать его каждый раз. Спасибо.
Евгений Х
хорошо, это хорошо, но у меня есть много сообщений, чтобы ждать, а затем показать. поэтому многогранные ступени создают проблему. Как можно решить проблему нескольких ступеней
Мехмет
2
Это решение вызывает утечку памяти, потому что оно использует нестатический внутренний и анонимный класс, который неявно содержит ссылку на его внешний класс, активность. См. Stackoverflow.com/questions/1520887/… для лучшего решения.
Тронман
@EugeneH Используйте живые шаблоны для облегчения жизни stackoverflow.com/a/16870791/4565796
Саид Арианманеш,
38

Вы можете использовать, CountDownTimerчто гораздо эффективнее, чем любое другое опубликованное решение. Вы также можете производить регулярные уведомления через определенные промежутки времени, используя его onTick(long)метод

Посмотрите на этот пример, показывающий обратный отсчет 30 секунд

   new CountDownTimer(30000, 1000) {
         public void onFinish() {
             // When timer is finished 
             // Execute your code here
     }

     public void onTick(long millisUntilFinished) {
              // millisUntilFinished    The amount of time until finished.
     }
   }.start();
Суфиян Гори
источник
23

Если вы часто используете задержку в своем приложении, используйте этот класс утилит

import android.os.Handler;


public class Utils {

    // Delay mechanism

    public interface DelayCallback{
        void afterDelay();
    }

    public static void delay(int secs, final DelayCallback delayCallback){
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                delayCallback.afterDelay();
            }
        }, secs * 1000); // afterDelay will be executed after (secs*1000) milliseconds.
    }
}

Использование:

// Call this method directly from java file

int secs = 2; // Delay in seconds

Utils.delay(secs, new Utils.DelayCallback() {
    @Override
    public void afterDelay() {
        // Do something after delay

    }
});
aruke
источник
1
Зачем ? Это чистые накладные расходы и сложность ... даром
juloo65
Если мы используем частые задержки, то хорошо бы иметь фиксированный формат задержек. Я не думаю, что есть много накладных расходов из-за одного дополнительного интерфейса и метода.
aruke
18

Используя Thread.sleep(millis)метод.

user2270457
источник
30
не делайте этого в потоке пользовательского интерфейса - другие элементы также могут перестать отвечать и позже будут вести себя непредсказуемо
jmaculate
1
Спасибо за предупреждение. это именно то, что мне нужно, чтобы задержать поток пользовательского интерфейса. идеальный ответ для моих нужд. Спасибо.
Хэмиш
7

Если вы хотите что-то делать в пользовательском интерфейсе через регулярные промежутки времени, очень хорошим вариантом является использование CountDownTimer:

new CountDownTimer(30000, 1000) {

     public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();
Иво Стоянов
источник
Это чище, чем Хэндлер .
Асан
3

Ответ обработчика в Котлине:

1 - Создайте функцию верхнего уровня внутри файла (например, файл, который содержит все ваши функции верхнего уровня):

fun delayFunction(function: ()-> Unit, delay: Long) {
    Handler().postDelayed(function, delay)
}

2 - Затем позвоните туда, где вам было нужно:

delayFunction({ myDelayedFunction() }, 300)
Фил
источник
2

Вы можете использовать это:

import java.util.Timer;

и для самой задержки добавьте:

 new Timer().schedule(
                    new TimerTask(){
                
                        @Override
                        public void run(){
                            
                        //if you need some code to run when the delay expires
                        }
                        
                    }, delay);

где delayпеременная в миллисекундах; например, установите delay5000 для 5-секундной задержки.

Дрор
источник
0

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

    public void fadeImageFunction(View view) {

    backgroundImage = (ImageView) findViewById(R.id.imageViewBackground);
    backgroundImage.animate().alpha(0f).setDuration(2000);

    // A new thread with a 2-second delay before changing the background image
    new Timer().schedule(
            new TimerTask(){
                @Override
                public void run(){
                    // you cannot touch the UI from another thread. This thread now calls a function on the main thread
                    changeBackgroundImage();
                }
            }, 2000);
   }

// this function runs on the main ui thread
private void changeBackgroundImage(){
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            backgroundImage = (ImageView) findViewById(R.id.imageViewBackground);
            backgroundImage.setImageResource(R.drawable.supes);
            backgroundImage.animate().alpha(1f).setDuration(2000);
        }
    });
}
MuharizJ
источник