我开发了一个应用程序,在Android模拟器屏幕上以指定的间隔显示一些文本。我正在使用Handler类。下面是我的代码片段:

handler = new Handler();
Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");               
    }
};
handler.postDelayed(r, 1000);

当我运行这个应用程序时,文本只显示一次。为什么?


当前回答

对于重复任务,您可以使用

new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);

就像这样

new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {

            }
        },500,1000);

上面的代码将在半秒后(500)第一次运行,并在每一秒后重复运行(1000)

在哪里

任务是要执行的方法

之后时间到初始执行

(重复执行的时间间隔)

其次

如果你想要执行Task的次数,你也可以使用CountDownTimer。

    new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval

     public void onTick(long millisUntilFinished) {
      }
      public void onFinish() {
     }
    }.start();

//Above codes run 40 times after each second

你也可以用runnable来做。创建一个可运行的方法

Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {

        }
    };

用这两种方式来称呼它

new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis  // to work on mainThread

OR

new Thread(runnable).start();//to work in Background 

其他回答

对于重复任务,您可以使用

new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);

就像这样

new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {

            }
        },500,1000);

上面的代码将在半秒后(500)第一次运行,并在每一秒后重复运行(1000)

在哪里

任务是要执行的方法

之后时间到初始执行

(重复执行的时间间隔)

其次

如果你想要执行Task的次数,你也可以使用CountDownTimer。

    new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval

     public void onTick(long millisUntilFinished) {
      }
      public void onFinish() {
     }
    }.start();

//Above codes run 40 times after each second

你也可以用runnable来做。创建一个可运行的方法

Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {

        }
    };

用这两种方式来称呼它

new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis  // to work on mainThread

OR

new Thread(runnable).start();//to work in Background 

对你的例子的简单修复是:

handler = new Handler();

final Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");
        handler.postDelayed(this, 1000);
    }
};

handler.postDelayed(r, 1000);

或者我们可以使用普通线程为例(与原来的Runner):

Thread thread = new Thread() {
    @Override
    public void run() {
        try {
            while(true) {
                sleep(1000);
                handler.post(this);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

thread.start();

您可以将可运行对象视为可以发送到消息队列执行的命令,而将处理程序视为用于发送该命令的帮助对象。

更多详情请访问http://developer.android.com/reference/android/os/Handler.html

我相信对于这种典型的情况,即运行具有固定间隔的东西,定时器更合适。这里有一个简单的例子:

myTimer = new Timer();
myTimer.schedule(new TimerTask() {          
@Override
public void run() {
    // If you want to modify a view in your Activity
    MyActivity.this.runOnUiThread(new Runnable()
        public void run(){
            tv.append("Hello World");
        });
    }
}, 1000, 1000); // initial delay 1 second, interval 1 second

使用Timer有几个优点:

初始延迟和间隔可以很容易地在schedule函数参数中指定 计时器可以通过调用myTimer.cancel()来停止。 如果你想只运行一个线程,记得在调度一个新线程之前调用myTimer.cancel()(如果myTimer不为空)

我认为可以改进Alex2k8的第一个解决方案,以提高每秒更新的正确性

1.原始代码:

public void run() {
    tv.append("Hello World");
    handler.postDelayed(this, 1000);
}

2.分析

在以上成本中,承担tv。append("Hello Word")花费T毫秒,显示500次后延迟时间为500*T毫秒 长时间运行会增加延时

3.解决方案

只需改变postDelayed()的顺序,以避免延迟:

public void run() {
    handler.postDelayed(this, 1000);
    tv.append("Hello World");
}

现在在Kotlin中,你可以这样运行线程:

class SimpleRunnable: Runnable {
    public override fun run() {
        println("${Thread.currentThread()} has run.")
    }
}
fun main(args: Array<String>) {
    val thread = SimpleThread()
    thread.start() // Will output: Thread[Thread-0,5,main] has run.
    val runnable = SimpleRunnable()
    val thread1 = Thread(runnable)
    thread1.start() // Will output: Thread[Thread-1,5,main] has run
}