如何以定义的时间间隔在 Android 中运行 Runnable 线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1921514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run a Runnable thread in Android at defined intervals?
提问by Rajapandian
I developed an application to display some text at defined intervals in the Android emulator screen. I am using the Handler
class. Here is a snippet from my code:
我开发了一个应用程序来在 Android 模拟器屏幕中以定义的间隔显示一些文本。我正在使用Handler
该类。这是我的代码片段:
handler = new Handler();
Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
}
};
handler.postDelayed(r, 1000);
When I run this application the text is displayed only once. Why?
当我运行这个应用程序时,文本只显示一次。为什么?
回答by alex2k8
The simple fix to your example is :
对您的示例的简单修复是:
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
Or we can use normal thread for example (with original Runner) :
或者我们可以使用普通线程(使用原始 Runner):
Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
handler.post(this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
You may consider your runnable object just as a command that can be sent to the message queue for execution, and handler as just a helper object used to send that command.
您可以将 runnable 对象视为可以发送到消息队列执行的命令,而将处理程序视为用于发送该命令的辅助对象。
More details are here http://developer.android.com/reference/android/os/Handler.html
更多细节在这里http://developer.android.com/reference/android/os/Handler.html
回答by user2212515
new Handler().postDelayed(new Runnable() {
public void run() {
// do something...
}
}, 100);
回答by NguyenDat
I think can improve first solution of Alex2k8 for update correct each second
我认为可以改进 Alex2k8 的第一个解决方案,以便每秒更新正确
1.Original code:
1.原代码:
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
2.Analysis
2.分析
- In above cost, assume
tv.append("Hello Word")
cost Tmilliseconds, after display 500times delayed time is 500*Tmilliseconds - It will increase delayed when run long time
- 在上述成本中,假设
tv.append("Hello Word")
成本为T毫秒,显示500次后延迟时间为500*T毫秒 - 长时间运行会增加延迟
3. Solution
3. 解决方案
To avoid that Just change order of postDelayed(), to avoid delayed:
为避免这种情况只需更改 postDelayed() 的顺序,以避免延迟:
public void run() {
handler.postDelayed(this, 1000);
tv.append("Hello World");
}
回答by Jawad Zeb
For repeating task you can use
对于重复任务,您可以使用
new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);
call it like
称之为
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
}
},500,1000);
The above code will run first time after half second(500)and repeat itself after each second(1000)
上面的代码将在半秒(500)后第一次运行,并在每一秒(1000)后重复自己
Where
在哪里
taskbeing the method to be executed
task是要执行的方法
afterthe time to initial execution
在初始执行时间 之后
(intervalthe time for repeating the execution)
(间隔重复执行的时间)
Secondly
其次
And you can also use CountDownTimerif you want to execute a Task number of times.
如果您想多次执行任务,也可以使用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
And you can also do it with runnable. create a runnable method like
你也可以用 runnable 来做到这一点。创建一个可运行的方法,如
Runnable runnable = new Runnable()
{
@Override
public void run()
{
}
};
And call it in both these ways
并以这两种方式调用它
new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis // to work on mainThread
OR
或者
new Thread(runnable).start();//to work in Background
回答by iTech
I believe for this typical case, i.e. to run something with a fixed interval, Timer
is more appropriate. Here is a simple example:
我相信对于这种典型情况,即以固定间隔运行某事Timer
更合适。这是一个简单的例子:
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
Using Timer
has few advantages:
使用Timer
有几个优点:
- Initial delay and the interval can be easily specified in the
schedule
function arguments - The timer can be stopped by simply calling
myTimer.cancel()
- If you want to have only one thread running, remember to call
myTimer.cancel()
beforescheduling a new one (if myTimer is not null)
- 可以在
schedule
函数参数中轻松指定初始延迟和间隔 - 只需调用即可停止计时器
myTimer.cancel()
- 如果只想运行一个线程,记得
myTimer.cancel()
在调度新线程之前调用(如果 myTimer 不为空)
回答by singh arjun
Handler handler=new Handler();
Runnable r = new Runnable(){
public void run() {
tv.append("Hello World");
handler.postDelayed(r, 1000);
}
};
handler.post(r);
回答by Damian Walczak
If I understand correctly the documentation of Handler.post() method:
如果我正确理解了 Handler.post() 方法的文档:
Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.
将 Runnable r 添加到消息队列中。runnable 将在此处理程序附加到的线程上运行。
So examples provided by @alex2k8, even though are working correctly, are not the same.
In case, where Handler.post()
is used, no new threads are created. You just post Runnable
to the thread with Handler
to be executed by EDT.
After that, EDT only executes Runnable.run()
, nothing else.
所以@alex2k8 提供的例子,即使工作正常,也不一样。如果Handler.post()
使用where ,则不会创建新线程。您只需发布Runnable
到Handler
要由EDT执行的线程即可。之后,EDT 只执行Runnable.run()
,不执行其他操作。
Remember:
Runnable != Thread
.
记住:
Runnable != Thread
。
回答by Khemraj
Kotlin
科特林
private lateinit var runnable: Runnable
override fun onCreate(savedInstanceState: Bundle?) {
val handler = Handler()
runnable = Runnable {
// do your work
handler.postDelayed(runnable, 2000)
}
handler.postDelayed(runnable, 2000)
}
Java
爪哇
Runnable runnable;
Handler handler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
// do your work
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(runnable, 1000);
}
回答by Animesh Shrivastav
An interesting example is you can continuously see a counter/stop-watch running in separate thread. Also showing GPS-Location. While main activity User Interface Thread is already there.
一个有趣的例子是你可以连续看到一个计数器/秒表在单独的线程中运行。还显示 GPS 位置。虽然主要活动用户界面线程已经存在。
Excerpt:
摘抄:
try {
cnt++; scnt++;
now=System.currentTimeMillis();
r=rand.nextInt(6); r++;
loc=lm.getLastKnownLocation(best);
if(loc!=null) {
lat=loc.getLatitude();
lng=loc.getLongitude();
}
Thread.sleep(100);
handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {
Toast.makeText(this, "Error="+e.toString(), Toast.LENGTH_LONG).show();
}
To look at code see here:
要查看代码,请参见此处:
回答by André Abboud
now in Kotlin you can run threads this way:
现在在 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
}