我有一个变量在我的代码说它是“状态”。
我想在应用程序中根据这个变量值显示一些文本。这必须在特定的时间延迟下完成。
这就像,
检查状态变量值 显示一些文本 等待10秒 检查状态变量值 显示一些文本 等待15秒
等等。时间延迟可能会有所不同,在文本显示时设置。
我试过Thread。睡眠(时间延迟),它失败。还有更好的办法吗?
我有一个变量在我的代码说它是“状态”。
我想在应用程序中根据这个变量值显示一些文本。这必须在特定的时间延迟下完成。
这就像,
检查状态变量值 显示一些文本 等待10秒 检查状态变量值 显示一些文本 等待15秒
等等。时间延迟可能会有所不同,在文本显示时设置。
我试过Thread。睡眠(时间延迟),它失败。还有更好的办法吗?
当前回答
基于上面关于ScheduledThreadPoolExecutor的帖子,我提出了一个适合我的需求的实用程序(想要每3秒触发一个方法):
class MyActivity {
private ScheduledThreadPoolExecutor mDialogDaemon;
private void initDebugButtons() {
Button btnSpawnDialogs = (Button)findViewById(R.id.btn_spawn_dialogs);
btnSpawnDialogs.setVisibility(View.VISIBLE);
btnSpawnDialogs.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
spawnDialogs();
}
});
}
private void spawnDialogs() {
if (mDialogDaemon != null) {
mDialogDaemon.shutdown();
mDialogDaemon = null;
}
mDialogDaemon = new ScheduledThreadPoolExecutor(1);
// This process will execute immediately, then execute every 3 seconds.
mDialogDaemon.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// Do something worthwhile
}
});
}
}, 0L, 3000L, TimeUnit.MILLISECONDS);
}
}
其他回答
在我的例子中,如果以下条件之一为真,我就必须执行一个流程:如果前一个流程已经完成,或者如果5秒已经过去了。所以,我做了以下工作,并且工作得很好:
private Runnable mStatusChecker;
private Handler mHandler;
class {
method() {
mStatusChecker = new Runnable() {
int times = 0;
@Override
public void run() {
if (times < 5) {
if (process1.isRead()) {
executeProcess2();
} else {
times++;
mHandler.postDelayed(mStatusChecker, 1000);
}
} else {
executeProcess2();
}
}
};
mHandler = new Handler();
startRepeatingTask();
}
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
}
如果process1被读取,它将执行process2。如果不是,则增加变量的时间,并使Handler在一秒钟后执行。它一直保持循环,直到process1被读取或times为5。当times为5时,这意味着5秒过去了,每一秒都执行process1.isRead()的if子句。
您可以使用Handler来发布可运行的代码。这里很好地概述了这项技术:https://guides.codepath.com/android/Repeating-Periodic-Tasks
基于上面关于ScheduledThreadPoolExecutor的帖子,我提出了一个适合我的需求的实用程序(想要每3秒触发一个方法):
class MyActivity {
private ScheduledThreadPoolExecutor mDialogDaemon;
private void initDebugButtons() {
Button btnSpawnDialogs = (Button)findViewById(R.id.btn_spawn_dialogs);
btnSpawnDialogs.setVisibility(View.VISIBLE);
btnSpawnDialogs.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
spawnDialogs();
}
});
}
private void spawnDialogs() {
if (mDialogDaemon != null) {
mDialogDaemon.shutdown();
mDialogDaemon = null;
}
mDialogDaemon = new ScheduledThreadPoolExecutor(1);
// This process will execute immediately, then execute every 3 seconds.
mDialogDaemon.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// Do something worthwhile
}
});
}
}, 0L, 3000L, TimeUnit.MILLISECONDS);
}
}
定时器工作正常。在这里,我使用定时器搜索1.5s后的文本和更新UI。希望这能有所帮助。
private Timer _timer = new Timer();
_timer.schedule(new TimerTask() {
@Override
public void run() {
// use runOnUiThread(Runnable action)
runOnUiThread(new Runnable() {
@Override
public void run() {
search();
}
});
}
}, timeInterval);
对于使用Kotlin的人来说,inazaruk的答案将不起作用,IDE将需要初始化变量,因此我们将在一个单独的方法中使用它,而不是在Runnable中使用postDelayed。
Initialize your Runnable like this : private var myRunnable = Runnable { //Do some work //Magic happens here ↓ runDelayedHandler(1000) } Initialize your runDelayedHandler method like this : private fun runDelayedHandler(timeToWait : Long) { if (!keepRunning) { //Stop your handler handler.removeCallbacksAndMessages(null) //Do something here, this acts like onHandlerStop } else { //Keep it running handler.postDelayed(myRunnable, timeToWait) } } As you can see, this approach will make you able to control the lifetime of the task, keeping track of keepRunning and changing it during the lifetime of the application will do the job for you.