在取消一次迭代并启动另一次迭代后让定时器工作的问题

时间:2011-04-22 01:53:32

标签: android timer handler

我被困在试图让我的计时器工作,我会做一个倒计时,然后再回去做另一个。

因此,在第二次拨打timer.scheduleAtFixedRate时,我收到了IllegalStateException,但我取消了TimerTask而不是Timer

我想要做的是倒计时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时,行为甚至更糟,因为我将new 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);
                    }
                }
        }
    });

希望有人可以指出我犯的一个简单错误。

以上是我Activity代码的一小段代码,因此我想要包含我认为需要显示的问题。

2 个答案:

答案 0 :(得分:1)

鉴于开发指南中的这篇文章:http://developer.android.com/resources/articles/timed-ui-updates.html以及此处的类似帖子:http://cart.kolix.de/?p=1438,我建议您更改策略并使用handler.postDelayed(this, 2000);

但是,特别是代码,我的猜测是它可能会被取消错误的任务。我真的不明白两次调用timer.scheduleAtFixedRate(timertask, 0, 1000);并在同一循环中先设置maxReps = 20;然后再设置maxReps = 10;的理由,因为循环不会等待任务完成之前仍在进行中。

因此,您向timer.scheduleAtFixedRate()发送了至少16个电话,但并非所有电话都可能在合适的时间取消。

答案 1 :(得分:0)

在尝试各种方法后,我终于找到了解决方案。

在我的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的运作方式。我发现各种方法效果不佳。