如何在android中设置延迟?


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

但这只是变成黑色。

Answers:


498

试试这个代码:

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
该解决方案解释了我在某些代码行中与处理程序有关的所有问题。
Sierisimo 2015年

45
我总是回到这篇文章,因为我懒得每次都写。谢谢。
尤金H

好吧,它会很好,但我有很多消息要等待然后显示。所以多重胎面会带来问题。如何解决多个胎面问题
mehmet

2
该解决方案会产生内存泄漏,因为它使用了一个非静态的内部和匿名类,该类隐式持有对其外部类(活动)的引用。请参阅stackoverflow.com/questions/1520887/…,以获得更好的解决方案。
tronman

@EugeneH使用实时模板简化生活stackoverflow.com/a/16870791/4565796
Saeed Arianmanesh

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

    }
});

1
为什么呢 这纯粹是开销和复杂性...一无是处
juloo65 '18

如果我们使用频繁的延迟,则采用固定格式的延迟就可以了。我认为没有额外的开销,因为有一个额外的接口和一种方法。
阿鲁克

18

使用Thread.sleep(millis)方法。


30
不这样做的UI线程-其他元素也可能会停止响应,后来行为异常
jmaculate

1
谢谢你的提醒。这正是我需要的,以延迟UI线程。我需要的完美答案。谢谢。
hamish

7

如果您想按固定的时间间隔在UI中执行某项操作,非常好的选择是使用CountDownTimer:

new CountDownTimer(30000, 1000) {

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

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();

它比Handler干净。
Ahsan

3

处理程序在Kotlin中的回答:

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变量是在毫秒; 例如设置delay5秒延迟为5000。


0

这是一个示例,其中我将背景图像从两个图像更改为另一个图像,同时具有2秒的alpha淡入延迟-将原始图像的2s淡入转换为2s的淡入第二图像。

    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);
        }
    });
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.