延迟执行方法 Java 中的代码
Delay execution of code in method Java
我想在我的 java (Android) 程序中每 2 秒生成一个随机数,持续至少 10 分钟。但我只想 pause/delay 只在一个方法中执行代码,而不是整个程序。
我试过像这样使用 Thread -
boolean stop = false;
int random_number = 0;
while(true){
if(stop){ //if stop becomes true, then
return; //terminate the method
}
random_number = Math.random(); //generate random number
//which is used bu some other
//part of code
try {
Thread.sleep(2000); //delay the code for 2 secs
} catch(InterruptedException ex) { //and handle the exceptions
Thread.currentThread().interrupt();
}
}
然而,这不起作用,因为 Thread.sleep
停止整个程序的执行,而不是仅仅停止方法内部代码的执行,我的整个屏幕变成空白。
我也尝试过使用 Handler
但它也没有用,因为它不会停止我方法中代码的执行,而是只是叠加。
这将更好地展示它的工作原理 -
while(true){
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
System.out.println("After 2 secs"); //this gets printed
//later
}
}, 2000);
System.out.println("Before 2 secs"); //this gets printed first
}
所以代码堆积起来,相当于使用 while 循环,并且速度非常慢。
此外,由于我正在为 Android 开发应用程序,我在 Java SE 6 上 运行,所以我无法使用 scheduleAtFixedRate
。还有其他方法可以实现吗?
非常感谢!
如果你想使用线程,这样做:
Thread t = new Thread(){
public void run(){
while(true){
if(stop) break;
random_number = Math.random();
sleep(2000);
}
}
};
t.start();
选项 1: 使用线程,您可能 运行 您的工作脱离主 (UI) 线程:
new Thread(new Runnable() {
// some code here ...
// This might be in a loop.
try {
Thread.sleep(2000);
} catch(InterruptedException ex) {
// Handle ...
}
}
}).start();
然后,如果你想修改这个新线程 UI(即 show/hide 按钮,在屏幕上显示一些东西等),请记住将其传递给 UI线程,因为只有这个可以修改 UI。您可以考虑为此使用 Activity.runOnUiThread()。
选项 2: 另一种更接近 Android 风格的方法是使用 AsyncTask。它包含三个回调,可用于在 UI 线程上和关闭时进行工作。此类代码的草图可能如下所示:
private class MyTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... param) {
// This method is running off the UI thread.
// Safe to stop execution here.
return null;
}
protected void onProgressUpdate(Void... progress) {
// This methid is running on the UI thread.
// Do not stop thread here, but safe to modify the UI.
}
protected void onPostExecute(Long result) {
// Also on UI thread, executed once doInBackground()
// finishes.
}
}
选项 3: 然后还有一个 Timer,正如@Stultuske 所建议的。它不如 AsyncTask
灵活,但会为您处理间隔。
private Timer timer;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//Generate number
}
}, 2000, 2000);
//Documentation (From SDK)
/**
* Schedule a task for repeated fixed-rate execution after a specific delay
* has passed.
*
* @param task
* the task to schedule.
* @param delay
* amount of time in milliseconds before first execution.
* @param period
* amount of time in milliseconds between subsequent executions.
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (delay < 0 || period <= 0) {
throw new IllegalArgumentException();
}
scheduleImpl(task, delay, period, true);
}
以及当你想停止它时
timer.cancel()
根据您的需要,您仍然可以使用 Handler 完成您想要的。
您不必在 while 循环中 create/start Handler(如您所见,除非您停止循环本身,否则它只会堆积起来,但这是无稽之谈)。
只需创建 Handler 并告诉他 post 延迟您的 Runnable 实例。在最后的 Runnable 中,您检查您的条件。如果它仍然正常,那么 post 另一个可运行的延迟,否则你什么都不做,处理程序将不再执行。
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("After 2 secs");
random_number = Math.random();
if (!stop) // should not be stopped, so we add another runnable;
{
handler.postDelayed(this, 2000);
}
}
handler.postDelayed(runnable, 2000);
唯一的缺点是,如果设备一段时间不使用,Handler 可能会死机,这意味着一旦设备屏幕打开,它就会从离开的地方开始倒计时。
它可以做 1 分钟的正确工作,然后当设备进入睡眠模式时在 1.4 秒时阻塞,一旦再次打开,Handler 将完成剩余的 0.6 秒。
不过,在不了解您的需求的情况下,您可能不会受到此行为的影响,而且答案可能适合您。
我想在我的 java (Android) 程序中每 2 秒生成一个随机数,持续至少 10 分钟。但我只想 pause/delay 只在一个方法中执行代码,而不是整个程序。
我试过像这样使用 Thread -
boolean stop = false;
int random_number = 0;
while(true){
if(stop){ //if stop becomes true, then
return; //terminate the method
}
random_number = Math.random(); //generate random number
//which is used bu some other
//part of code
try {
Thread.sleep(2000); //delay the code for 2 secs
} catch(InterruptedException ex) { //and handle the exceptions
Thread.currentThread().interrupt();
}
}
然而,这不起作用,因为 Thread.sleep
停止整个程序的执行,而不是仅仅停止方法内部代码的执行,我的整个屏幕变成空白。
我也尝试过使用 Handler
但它也没有用,因为它不会停止我方法中代码的执行,而是只是叠加。
这将更好地展示它的工作原理 -
while(true){
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
System.out.println("After 2 secs"); //this gets printed
//later
}
}, 2000);
System.out.println("Before 2 secs"); //this gets printed first
}
所以代码堆积起来,相当于使用 while 循环,并且速度非常慢。
此外,由于我正在为 Android 开发应用程序,我在 Java SE 6 上 运行,所以我无法使用 scheduleAtFixedRate
。还有其他方法可以实现吗?
非常感谢!
如果你想使用线程,这样做:
Thread t = new Thread(){
public void run(){
while(true){
if(stop) break;
random_number = Math.random();
sleep(2000);
}
}
};
t.start();
选项 1: 使用线程,您可能 运行 您的工作脱离主 (UI) 线程:
new Thread(new Runnable() {
// some code here ...
// This might be in a loop.
try {
Thread.sleep(2000);
} catch(InterruptedException ex) {
// Handle ...
}
}
}).start();
然后,如果你想修改这个新线程 UI(即 show/hide 按钮,在屏幕上显示一些东西等),请记住将其传递给 UI线程,因为只有这个可以修改 UI。您可以考虑为此使用 Activity.runOnUiThread()。
选项 2: 另一种更接近 Android 风格的方法是使用 AsyncTask。它包含三个回调,可用于在 UI 线程上和关闭时进行工作。此类代码的草图可能如下所示:
private class MyTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... param) {
// This method is running off the UI thread.
// Safe to stop execution here.
return null;
}
protected void onProgressUpdate(Void... progress) {
// This methid is running on the UI thread.
// Do not stop thread here, but safe to modify the UI.
}
protected void onPostExecute(Long result) {
// Also on UI thread, executed once doInBackground()
// finishes.
}
}
选项 3: 然后还有一个 Timer,正如@Stultuske 所建议的。它不如 AsyncTask
灵活,但会为您处理间隔。
private Timer timer;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//Generate number
}
}, 2000, 2000);
//Documentation (From SDK)
/**
* Schedule a task for repeated fixed-rate execution after a specific delay
* has passed.
*
* @param task
* the task to schedule.
* @param delay
* amount of time in milliseconds before first execution.
* @param period
* amount of time in milliseconds between subsequent executions.
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (delay < 0 || period <= 0) {
throw new IllegalArgumentException();
}
scheduleImpl(task, delay, period, true);
}
以及当你想停止它时
timer.cancel()
根据您的需要,您仍然可以使用 Handler 完成您想要的。
您不必在 while 循环中 create/start Handler(如您所见,除非您停止循环本身,否则它只会堆积起来,但这是无稽之谈)。
只需创建 Handler 并告诉他 post 延迟您的 Runnable 实例。在最后的 Runnable 中,您检查您的条件。如果它仍然正常,那么 post 另一个可运行的延迟,否则你什么都不做,处理程序将不再执行。
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("After 2 secs");
random_number = Math.random();
if (!stop) // should not be stopped, so we add another runnable;
{
handler.postDelayed(this, 2000);
}
}
handler.postDelayed(runnable, 2000);
唯一的缺点是,如果设备一段时间不使用,Handler 可能会死机,这意味着一旦设备屏幕打开,它就会从离开的地方开始倒计时。
它可以做 1 分钟的正确工作,然后当设备进入睡眠模式时在 1.4 秒时阻塞,一旦再次打开,Handler 将完成剩余的 0.6 秒。
不过,在不了解您的需求的情况下,您可能不会受到此行为的影响,而且答案可能适合您。