2011-04-22 45 views
0

我卡住試圖讓我的計時器工作,我會做一個倒計時,然後回去做另一個。取消計時器工作後取消一個迭代,並開始另一個

因此,在第二次調用timer.scheduleAtFixedRate我得到一個IllegalStateException,但我取消TimerTask不是Timer

我想要做的是倒計時二十秒,然後十秒鐘,然後重複,每次更新一個文本框,以通知用戶他們應該做什麼。

一個問題是,倒數比一秒/秒快。

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) 

下面是我用這樣的嘗試的代碼。當我試圖在每個循環中使用不同的時間任務時,這是更差的行爲,因爲我在timer.scheduleAtFixedRate之前放置了new TimerTask塊,所以我回到了這個版本。

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代碼片段,所以我只包括我認爲需要顯示的問題。

回答

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;在同一個循環中的原因,因爲在繼續之前,循環不會等待任務完成。

因此,您至少要發送16個電話給timer.scheduleAtFixedRate(),並非所有人都可能在正確的時間取消。

+0

我會再次嘗試handler.postDelayed方法。我試過了,無法讓它做我想做的事。我傾向於使用Thread.sleep(1000),這會強制我的活動暫停,然後顯示更新並繼續。 – 2011-04-22 12:10:49

+0

@James Thread.sleep應該可以工作。我認爲問題是有一個循環分配一個靜態/全局變量(maxReps)並啓動異步任務來讀取它。在等待時阻止for循環應該可以解決這個問題。 – Aleadam 2011-04-22 13:29:11

+0

thread.sleep不起作用,因爲它無法訪問UI組件,而且似乎搞亂了Activity的工作方式,而且PostDelayed也無法訪問UI組件,所以我最終不得不去找經理。 – 2011-04-25 02:11:08

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的工作原理。我發現各種方法不能很好地工作。

相關問題