Android 在取消一个迭代并开始另一个迭代后使计时器工作时出现问题
我被困在试图让我的计时器工作,在那里我会做一个倒计时,然后回去做另一个 因此,在第二次调用Android 在取消一个迭代并开始另一个迭代后使计时器工作时出现问题,android,timer,handler,Android,Timer,Handler,我被困在试图让我的计时器工作,在那里我会做一个倒计时,然后回去做另一个 因此,在第二次调用timer.scheduleAtFixedRate时,我得到了一个非法状态异常,但我正在取消TimerTask而不是计时器 我想做的是倒计时20秒,然后10秒,然后重复,每次更新一个文本框,通知用户他们应该做什么 一个问题是倒计时比一次/秒快 04-22 01:34:57.118: DEBUG/TestHandler1(404): message called:2:null 04-22 01:34:57.7
timer.scheduleAtFixedRate
时,我得到了一个非法状态异常
,但我正在取消TimerTask
而不是计时器
我想做的是倒计时20秒,然后10秒,然后重复,每次更新一个文本框,通知用户他们应该做什么
一个问题是倒计时比一次/秒快
04-22 01:34:57.118: DEBUG/TestHandler1(404): message called:2:null
04-22 01:34:57.709: DEBUG/TestHandler1(404): message called:3:null
04-22 01:34:57.899: DEBUG/TestHandler1(404): message called:4:null
04-22 01:34:58.198: DEBUG/TestHandler1(404): message called:5:null
以下是我的例外:
04-22 01:35:48.529: ERROR/AndroidRuntime(404): java.lang.IllegalStateException: TimerTask is scheduled already
04-22 01:35:48.529: ERROR/AndroidRuntime(404): at java.util.Timer.scheduleImpl(Timer.java:574)
04-22 01:35:48.529: ERROR/AndroidRuntime(404): at java.util.Timer.scheduleAtFixedRate(Timer.java:530)
下面是我用于此尝试的代码。当我尝试为每个循环使用不同的timertask时,情况更糟,因为我将新timertask
块放在timer.scheduleAtFixedRate
之前,所以我回到了这个版本
handler = new Handler() {
public void handleMessage(Message msg) {
counterText.setText((new Date()).toString() + " "
+ Integer.toString(cntr));
System.out.println("handleMessage");
}
};
timertask = new TimerTask() {
public void run() {
handler.sendEmptyMessage(0);
cntr++;
if (cntr > maxReps) {
timertask.cancel();
cntr = 0;
}
}
};
doneButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
cntr = 0;
for (MyClass mclass : input.getLoop()) {
labelText.setText(mclass.getName());
for (int y = 0; y < 8; y++) {
maxReps = 20;
timer.scheduleAtFixedRate(timertask, 0, 1000);
maxReps = 10;
labelText.setText("Rest");
timer.scheduleAtFixedRate(timertask, 0, 1000);
}
}
}
});
handler=newhandler(){
公共无效handleMessage(消息消息消息){
counterText.setText((新日期()).toString()+“”
+整数.toString(cntr));
System.out.println(“handleMessage”);
}
};
timertask=新的timertask(){
公开募捐{
handler.sendEmptyMessage(0);
cntr++;
如果(cntr>maxReps){
timertask.cancel();
cntr=0;
}
}
};
doneButton.setOnClickListener(新视图.OnClickListener(){
公共void onClick(视图v){
cntr=0;
for(MyClass mclass:input.getLoop()){
labelText.setText(mclass.getName());
对于(int y=0;y<8;y++){
最大重复次数=20;
timer.scheduleAtFixedRate(timertask,0,1000);
最大重复次数=10;
labelText.setText(“其余”);
timer.scheduleAtFixedRate(timertask,0,1000);
}
}
}
});
希望有人能指出我犯的一个简单错误
以上是我在
活动中的一段代码,因此我只包含了我认为需要的内容,以显示我的问题所在。鉴于《开发指南》中的这篇文章和这里的一篇类似文章:,我建议您更改策略并使用handler.postDelayed(this,2000)代码>
但是,特别是对于代码,我的猜测是它可能会被错误的任务取消。我真的不理解对timer.scheduleAtFixedRate(timertask,01000)进行两次调用的原理代码>和设置maxReps=20代码>首先,然后maxReps=10代码>在同一循环中,因为循环不会等待任务完成后再继续
因此,您至少向timer.scheduleAtFixedRate()发送了16个调用。在尝试了各种方法后,我最终确定了这个解决方案
在我的OnCreate
方法中,我有这段代码,它会持续20秒,然后退出
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
String s = msg.getData().getString("counter");
counterText.setText(s);
Log.d("Activity.handleMessage", s);
}
};
final Runnable runnable = new Runnable() {
@Override
public void run() {
final long start = SystemClock.uptimeMillis();
while (true) {
Message m = new Message();
Bundle b = new Bundle();
b.putString("counter", Integer.toString(cntr));
m.setData(b);
handler.sendMessageDelayed(m, cntr * 1000);
if (cntr++ == maxReps) {
return;
}
}
}
};
doneButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
exerciseText.setText(model.getName());
counterText.setText("0");
maxReps = 20;
handler.postDelayed(runnable, 1000);
});
我的部分困难不在于思考Android是如何工作的。我发现各种方法都不太管用。我将再次尝试handler.postDelayed方法。我试过了,但没能让它做我想做的。我倾向于只使用Thread.sleep(1000),这将迫使我的活动暂停,然后我显示更新,然后继续。@James Thread.sleep应该可以工作。我认为问题在于让一个循环分配一个静态/全局变量(maxReps)并启动异步任务来读取它。在等待时阻塞for循环应该可以解决这个问题。thread.sleep不起作用,因为它无法访问UI组件,并且似乎扰乱了活动的工作方式,postDelayed也无法访问UI组件,因此我最终不得不访问处理程序。