我有一个变量在我的代码说它是“状态”。
我想在应用程序中根据这个变量值显示一些文本。这必须在特定的时间延迟下完成。
这就像,
检查状态变量值 显示一些文本 等待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);
}
}
其他回答
试试下面的例子,它可以工作!!
在onCreate()方法中使用[Handler],该方法使用postDelayed()方法,该方法会导致Runnable被添加到消息队列中,在给定的示例中,在指定的时间流逝后运行。1
参考以下代码:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//------------------
//------------------
android.os.Handler customHandler = new android.os.Handler();
customHandler.postDelayed(updateTimerThread, 0);
}
private Runnable updateTimerThread = new Runnable()
{
public void run()
{
//write here whaterver you want to repeat
customHandler.postDelayed(this, 1000);
}
};
我认为新的热点是使用ScheduledThreadPoolExecutor。像这样:
private final ScheduledThreadPoolExecutor executor_ =
new ScheduledThreadPoolExecutor(1);
this.executor_.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
update();
}
}, 0L, kPeriod, kTimeUnit);
在我的例子中,如果以下条件之一为真,我就必须执行一个流程:如果前一个流程已经完成,或者如果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子句。
有3种方法:
使用ScheduledThreadPoolExecutor
有点多余,因为你不需要一个线程池
//----------------------SCHEDULER-------------------------
private final ScheduledThreadPoolExecutor executor_ =
new ScheduledThreadPoolExecutor(1);
ScheduledFuture<?> schedulerFuture;
public void startScheduler() {
schedulerFuture= executor_.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
//DO YOUR THINGS
pageIndexSwitcher.setVisibility(View.GONE);
}
}, 0L, 5*MILLI_SEC, TimeUnit.MILLISECONDS);
}
public void stopScheduler() {
pageIndexSwitcher.setVisibility(View.VISIBLE);
schedulerFuture.cancel(false);
startScheduler();
}
使用定时器任务
旧Android风格
//----------------------TIMER TASK-------------------------
private Timer carousalTimer;
private void startTimer() {
carousalTimer = new Timer(); // At this line a new Thread will be created
carousalTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//DO YOUR THINGS
pageIndexSwitcher.setVisibility(INVISIBLE);
}
}, 0, 5 * MILLI_SEC); // delay
}
void stopTimer() {
carousalTimer.cancel();
}
使用Handler和Runnable
现代安卓风格
//----------------------HANDLER-------------------------
private Handler taskHandler = new android.os.Handler();
private Runnable repeatativeTaskRunnable = new Runnable() {
public void run() {
//DO YOUR THINGS
}
};
void startHandler() {
taskHandler.postDelayed(repeatativeTaskRunnable, 5 * MILLI_SEC);
}
void stopHandler() {
taskHandler.removeCallbacks(repeatativeTaskRunnable);
}
无泄漏的处理程序与活动/上下文
在Activity/Fragment类中声明一个不会泄漏内存的内部Handler类
/**
* Instances of static inner classes do not hold an implicit
* reference to their outer class.
*/
private static class NonLeakyHandler extends Handler {
private final WeakReference<FlashActivity> mActivity;
public NonLeakyHandler(FlashActivity activity) {
mActivity = new WeakReference<FlashActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
FlashActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
声明一个runnable来执行Activity/Fragment类中的重复任务
private Runnable repeatativeTaskRunnable = new Runnable() {
public void run() {
new Handler(getMainLooper()).post(new Runnable() {
@Override
public void run() {
//DO YOUR THINGS
}
};
在你的Activity/Fragment中初始化Handler对象(这里FlashActivity是我的Activity类)
//Task Handler
private Handler taskHandler = new NonLeakyHandler(FlashActivity.this);
在固定的时间间隔后重复一项任务
taskHandler。postDelayed(repeatativeTaskRunnable, DELAY_MILLIS);
停止重复任务
taskHandler .removeCallbacks(repeatativeTaskRunnable );
更新:在Kotlin:
//update interval for widget
override val UPDATE_INTERVAL = 1000L
//Handler to repeat update
private val updateWidgetHandler = Handler()
//runnable to update widget
private var updateWidgetRunnable: Runnable = Runnable {
run {
//Update UI
updateWidget()
// Re-run it after the update interval
updateWidgetHandler.postDelayed(updateWidgetRunnable, UPDATE_INTERVAL)
}
}
// SATART updating in foreground
override fun onResume() {
super.onResume()
updateWidgetHandler.postDelayed(updateWidgetRunnable, UPDATE_INTERVAL)
}
// REMOVE callback if app in background
override fun onPause() {
super.onPause()
updateWidgetHandler.removeCallbacks(updateWidgetRunnable);
}
定时器工作正常。在这里,我使用定时器搜索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);