2012-01-31 53 views
0

我正在嘗試爲Android創建一個簡單的鍛鍊計時器。用戶創建一個包含總持續時間,總休息時間等信息的WorkoutPlan,應用程序將顯示一個每秒更新一次的計時器。如何用線程構建Android定時器應用程序?

很簡單的開始,但我試圖儘可能正確地,即關注,正確的技術,反應靈敏的用戶界面,保證了計時器將被準確的分離構建應用程序等

這裏有一個什麼我迄今爲止的簡化:

WorkoutPlan,用戶可以加載/不同的鍛鍊計劃保存到計時器

public class WorkoutPlan { 
    public long duration; 
} 

TimerThread,這個類實現Runnable,它取在啓動/停止構造函數中,在WorkoutPlan中顯示已用時間。

public class TimerThread implements Runnable { 
    public boolean running = false; 

    private long lastStartTime; 
    private long savedTime; 
    private WorkoutPlan plan; 
    private Handler handler; 

    public TimerThread(WorkoutPlan p, Handler h) { 
     plan = p; 
     handler = h; 
    } 

    public synchronized void start() { 
     lastStartTime = System.currentTimeMillis(); 
     running = true; 
    } 

    public synchronized void pause() { 
     savedTime = elapsedTime(); 
     lastStartTime = 0; 
     running = false; 
    } 

    public synchronized long elapsedTime() { 
     if (lastStartTime == 0) { 
      return savedTime; 
     } else { 
      return savedTime + (System.currentTimeMillis() - lastStartTime); 
     } 
    } 

    public synchronized String currTimeStr() { 
     //format elapsed time in seconds to hh:mm:ss format 
     long elapsed = elapsedTime()/1000; 
     long h = elapsed/3600; 
     long m = (elapsed % 3600)/60; 
     long s = elapsed % 60; 

     if (h > 0) { 
      return String.format("%02d:%02d:%02d", h, m, s); 
     } else { 
      return String.format("%02d:%02d", m, s); 
     } 
    } 

    @Override 
    public void run() { 
     while (running) { 
      try { 
       handler.sendMessage(handler.obtainMessage()); 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

TimerView,顯示經過的時間

public class TimerView extends View { 
    private final Paint mBg; 
    private final Paint mText; 
    private WorkoutPlan plan; 
    private TimerThread timer; 
    private Thread thread; 
    private Handler handler = new TimerHandler(); 

    public TimerView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     plan = new WorkoutPlan(); 

     timer = new TimerThread(plan, handler);   
     thread = new Thread(timer); 

     mBg = new Paint(); 
     mBg.setColor(getResources().getColor(R.color.bg_default)); 
     mText = new Paint(); 
     mText.setColor(getResources().getColor(R.color.text)); 
    } 

    public void start() { 
     timer.start(); 
     thread.start(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     //draw current time and current round 
     canvas.drawText(timer.currTimeStr(), 0, 50, mText); 
    } 

    private class TimerHandler extends Handler { 

     @Override 
     public void handleMessage(Message msg) { 
      super.handleMessage(msg); 
      invalidate(); 
     }   
    } 
} 

最後,WorkoutTimer自定義視圖,啓動它關閉

public class WorkoutTimer extends Activity { 
    private TimerView mTimer; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.timer); 

     mTimer = (TimerView) findViewById(R.id.timer_view); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart();   
     mTimer.start(); 
    } 
} 

幾個問題的活動:

  1. 哪裏是創建WorkoutPlan對象的最佳地點?目前它在TimerView完成。是否應該在WorkoutTimer活動中完成?如果是的話,我如何將WorkoutPlan對象傳遞給TimerView
  2. 該應用第一次正常工作,但是當我進入主屏幕然後第二次回到應用時崩潰。什麼導致它崩潰?它是首字母嗎?
  3. 當前我在新的Thread中使用了Handler。這是好的還是會TimerTask更好?哪裏是開始線程的最佳地點?
  4. 我正確的把所有的線程代碼放在TimerView?感覺他們應該在別的地方。
  5. 我是否正確添加同步到TimerThread中的所有方法?
  6. 我試圖創建這個應用程序,因爲我可以練習。請讓我知道,如果我應該做的技術有所改進,或者如果我做了不正確的事情。

回答

0

如果你問的是風格,很糟糕的風格是在某些變體中使用「計時器」這個詞來實現不是Timer,而是完全不同的類Handler。使用一些其他的名字。現在代碼幾乎是不可讀的。