Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在取消一个迭代并开始另一个迭代后使计时器工作时出现问题_Android_Timer_Handler - Fatal编程技术网

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组件,因此我最终不得不访问处理程序。